`
msn877763580
  • 浏览: 81167 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

关于java变量的几个概念

 
阅读更多

成员变量:指类范围内定义的变量。(实例属性,类属性(以static修饰))


实例属性和类属性的区别:

一个是类的方法(也叫动态属性)和属性(静态属性),通过类名来访问;
一个是对象的方法和属性,需要通过一个实例来访问。
静态属性程序一加载时 就初始化 存放在栈中;
实例属性 需要实例化后 才加载 存放在堆中。


局部变量:指的是一个方法内的变量。(形参,方法局部变量,代码块局部变量)


关于变量初始化的顺序,以及new一个对象时会不会同时产生一个父类的对象,甚至是Object对象,ITeye上收集的信息如下,个人认为比较的详细。

huoyj写道
类加载主要有三个过程:装载,链接和初始化。
装载是最好理解的,就是将编译生成的二进制文件装到内存中。
链接:这个过程又可以分为三个子过程,即校验,准备和解析,校验当然就是对已装入内存中的二进制类文件校验,检查其是否符合class文件的规范,同时它还要提取一些类的关键信息,比如变量和方法。准备就是对类变量分配存储空间,同时会初始化。解析:将符号引用转成直接引用;也就是对引用变量分配空间,并初始化。注意;在链接的时候会对变量分配空间并初始化,但这时候的初始化并不是很可靠的。
初始化:这时候会执行真正的初始化语句即执行构造方法对变量初始化。
由以上的过程可以得出在类加载的时候执行的顺序为:静态变量ok -> 静态代码块 -> 变量ok -> 普通代码块 -> 构造方法开始执行。


 

jameswxx 写道
当new一个对象的时候发生了什么?我就给大家讲讲吧,如果不对的地方,还请大家指正
如new MyObject();

1:寻找类定义
jvm会在自己的一个名叫“方法区”的内存块中,寻找名叫“MyObject”的Class对象(注意class也是一个对象,该对象记录了所有类的定义),如果有,则按照Class对象的定义,生成一个MyObject对象。

2:加载类定义
如果“方法区”中没有名为“MyObject”的Class对象,jvm会用当前类的类加载器(classloader)从当前的classpath路径寻找名为"MyObject.class"的文件,如果找到,则将文件进行分析,转换为Class对象存放在“方法区”中,否则抛出“ClassNotFoundException”。对于jdk的class,jvm启动时,会用启动类加载器加载,对于用户的class,则会用应用程序类加载器实时加载,所谓实时加载,指的是遇到的时候再加载,而不是预先一次性加载。关于类加载器,有三级,jvm严格的限制了每一级的加载权限,加载模式为“双亲委托模式”,加载任何类,都先由父加载器加载。

3:给对象分配内存空间
找到MyObject的类定义后,jvm在内存“堆”中,开辟一个空间,该空间按照MyObject类定义开辟,并将该空间中的各个内存段设置默认值,对应的就是对象的属性初始化默认值。

4:对象的初始化顺序
对象的初始化都先从父类开始,顺序如下:
给父类静态变量默认值
对父类静态变量赋值
执行父类静态块

给当前类静态变量默认值
对当前类静态变量赋值
执行当前类静态块

给父类变量默认值
对父类变量赋值
执行父类构造函数

给当前类变量默认值
对当前类变量赋值
执行当前类构造函数

5:对象构造完成

还有一点要提醒楼主,当你new一个String的时候,只是生成一个String对象,而没有生成Object对象,Object的类定义在“方法区”这块内存中,当new String的时候,jvm会检查String的父类,找出父类的定义,并找出哪些是String可以拥有的,然后按照筛选出来的父类定义和String本身的类定义,在堆中分配一个内存块(就是俗称的生成了一个对象),而没有专门为String的父类Object分配空间。

其实你可以想想下,如果像你那么说,new一个String的时候,还会生成一个Object对象,那java简直没法使用了,因为Obejct是所有对象的父类,使用任何对象都会生成一个Object对象,还不算其他的父类。如果这样,多大的内存也不够用,即使内存够了,CPU也会忙死,因为这么多对象,后台的gc执行一次收集清除,都累得够呛了。特别是现在的gc机制都是按代收集的,对象巨多,年轻代很容易满,导致gc收集启动,应用程序会停顿。这样的系统谁能用呢?

 对于jameswxx中所说的对象的初始化顺序不能完全赞同,下面引用臧圩人·海纳百川的文章说明。

臧圩人·海纳百川 写道
public class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
// 构造器
public Parent() {
System.out.println("父类--构造器");
}
}

public class SubClass extends Parent{
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
// 构造器
public SubClass() {
System.out.println("子类--构造器");
}
// 程序入口
public static void main(String[] args) {
new SubClass();
}
}

执行结果:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器


臧圩人·海纳百川 写道
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。
静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。


 

分享到:
评论

相关推荐

    Java基础教案\JAVA精讲入门

    4.给出平台的搭建步骤,重点讲解几个环境变量设置的意义 5.第1个Java程序:编程实例操作示范,向学生示范编写、编译与运行Java程序的3个完整步骤。强调Java程序的命名规则。 6.示范结束后,学生模仿编写程序; 7...

    corejava基础重要知识点总结

    java的优势? 1:跨平台(平台:指的是操作系统) ... 1:在设置环境变量的时候 最少需要设置几个环境变量? 0个 2:在设置环境变量的时候 通常需要设置几个环境变量? 1个 -》 PATH -> jdk/bin

    Java数据挖掘包JDMP0.1.1 jar文件

    例如,可以将几个矩阵组合成一个变量,如,一个时间序列。可以一个一个地访问这些矩阵,也可以作为一个单个的大型矩阵来进行访问。可以将几个变量组合成一个样本,如,在分类中有输入值和目标值的样本。许多样本可以...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 类、消息、接口、及抽象等概念。 2.2.1 对象 现实世界中的对象具两个特征:状态和行为。例如:自行车有状态(传动装置、步度、 两个车轮和...

    JAVA面试题最全集

    5.j2me程序的必需的几个部分 6.c/s与b/s的区别 7.构建一个connect pool,然后再调用它, 8.j2ee平台与dotnet平台的区别 9.ejb的life cycle 10.session bean 和 entity bean的区别 11.ejb中的transaction机制 ...

    java初学者必看

    8.5 关于设计好继承的几点建议 8.6 实例:一卡通类的继承 8.6.1 构造方法 8.6.2 setter方法 8.6.3 getter方法 8.6.4 方法覆盖 8.6.5 equals方法 8.6.6 其他需要强调的地方 8.7 本章习题 第9章 多态与抽象类...

    Java第三章习题

    阐述Java语言是如何支持面向对象的抽象和封装概念? 2.在Java程序中可以通过哪几个途径对成员变量初始化?

    java 面试题 总结

    创建了几个String Object? 两个 28、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。 以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。 public class ThreadTest1{ ...

    Java学习路线.pdf

    学习 Java 的路线可以大致分为以下几个阶段: 学习基础:首先需要掌握 Java 的基础知识,包括语法、数据类型、变量、运算符、控制流程、数组、字符串等。可以通过阅读教程、参加在线课程或自学来获得这些基础知识。...

    java面试宝典

    244、客服端调用EJB对象的几个基本步骤 56 245、 如何给weblogic指定大小的内存? 56 246、如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 57 247、如何启动时不需输入用户名与密码? 57 248、在...

    浅谈Android中关于静态变量(static)的使用问题

    初步排除了oom和cpu紧张问题,因为是工业平板不方便调试,用了些比较笨的方法最后锁定在几个用了static的地方。在这里记录下Android中使用static的一些问题。 静态变量的生命周期遵守Java的设计。静态变量在类被load...

    java面试800题

    Q0043 java相关概念 "static:静态,无需实例化,可直接引用,全局只有一份copy,修饰变量和方法 final:最终的,不可继承、不可修改,修饰变量、方法、类 volatile:volatile变量表示保证它必须是与主内存保持一致,...

    Java语言基础下载

    DOM以及广义的基于树的处理具有几个优点 399 文档对象模型(DOM)解析实例 402 DOM对象 404 DOM解析的例子: 406 SAX解析实例 409 DOM4J解析实例 412 JDOM解析实例 413 JAVA操纵XML 实例讲解 414 通过JAVA写数据到...

    Java面试宝典-经典

    16. hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决; 123 17.介绍一下Hibernate的二级缓存 123 18、Spring 的依赖注入是什么意思? 给一个 Bean 的 message ...

    Java面试宝典2010版

    16. hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决; 123 17.介绍一下Hibernate的二级缓存 123 18、Spring 的依赖注入是什么意思? 给一个 Bean 的 message ...

    2023最新整理版-java基础面试提

    2023最新整理,java基础面试题,涵盖基础概念与常识、基本语法、基本数据类型、面向对象基础、Java常见类、异常、泛型、反射、注解、SPI、序列化和发序列化等知识点,目录清洗,共有近60个基础知识面试题以及详细...

    java面试题大全(2012版)

    16. hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决; 123 17.介绍一下Hibernate的二级缓存 123 18、Spring 的依赖注入是什么意思? 给一个 Bean 的 message ...

    JAVA面试题JAVA面试题JAVA面试题JAVA面试题

    四、准备几个问题 面试主要是考察毕业生对单位和职位的了解程度、毕业生的专业知识和技能,以及他们的社会意识、综合素质、敬业精神等。所以在谈话和提问式的面试中,总有一些问题是面试者常常提问的,例如:“简单...

Global site tag (gtag.js) - Google Analytics