`
sudongyuan
  • 浏览: 58862 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

main()方法的执行 和 类加载

阅读更多

存在这么一个类:

public class test2 {
    
           public int noStaticNum = printNoStaticNum();  
             
           public static  int staticNum = printStaticNum();  
           
           public static final int aaa = 111 ;
           
           public final int bbb = 222 ;
           
           static {  
               System.out.println("执行静态块!");  
           }  
            
          public static int printStaticNum() {  
              System.out.println("execute printStaticNum() method !");  
              return 1;  
          }  
            
          public int printNoStaticNum() {  
              System.out.println("execute printNoStaticNum() method !");  
              return 1;  
          }  
            
          public static void main(String[] args) {  
             
          }  
      }

 

1、类的实例化 test2 t1 = new test2() ;

实例化的结果是打印:

execute printStaticNum() method !
执行静态块!
execute printNoStaticNum() method !

 

实例化过程其实分开了说有两个过程:类加载和实例化的过程

类加载的过程大概包括以下过程(详情可以参考深入JVM这本书):

           * 1、把字节码文件转换为二进制文件
           * 2、在方法区中形成内部数据结构.(类中局部变量、方法、父类引用等)
           * 3、验证类文件中数据合法性
           * 4、初始化的过程(主要给静态变量和静态块初始化)

实例化的过程包括:

          * 1、实例化主要的工作是在内存堆中生成一个对象实例
          * 2、生成的实例会进行内部局部变量的初始化等

 

进行运行结果的验证:

直接执行这个类的结果是:

execute printStaticNum() method !
执行静态块!

可以发现运行main()并没有对局部变量进行初始化,那么是否运行main()没有实例化呢?内存中是否存在test2的对象呢?如果存在,又是一个什么样的形态呢?今天没时间了,以后验证吧!

 

2、Class.forName()和newInstance()

Class.forName()方法是加载的过程

newInstance()是一个实例化的过程

 

//利用默认的构造器生成对象
 test2 t2 = (test2)Class.forName("com.sudongyuan.test2").newInstance();

//如果类中有多个构造器可以选择相应的构造器生成对象
test2 t3 = (test2)Class.forName("com.sudongyuan.test2").getConstructors()[0].newInstance("");

 

3、反射机制,利用方法名调用对象方法

         Class a = Class.forName("com.sudongyuan.test2") ;
          Method b = a.getMethod("printNoStaticNum",null);
          b.invoke(a.newInstance(), null);

 

4、验证静态变量和非静态变量的区别(还有final变量)

         /* 验证静态变量和非静态变量的区别
           * 1、静态变量是所有的类实例共享,其中一个实例对其进行了修改会在别的类实例中反映出来
           * 2、非静态变量是实例独享,对其的改动不会反映到别的对象中
           * 3、final变量不能进行重新附值,所以在使用中final int a = 0 和final static int a = 0
           * 应该是一样的。区别是
           * */
          test2 f = (test2)a.newInstance() ;
          f.staticNum = 99000 ;
          f.noStaticNum = 29999 ;        

System.out.println(((test2)a.newInstance()).staticNum + " " + ((test2)a.newInstance()).noStaticNum );

打印的结果是:99000   1

 

类中有这两个final变量

   public static final int aaa  ;  
   public final int bbb  ;

 

对static final aaa,根据有的书中介绍说在编译时候就会把aaa转换为常量定义形式,但是在编译后的Class文件中,aaa并没有转换(这个还有待以后验证)。

那么aaa和bbb有什么区别呢?根据static的区别,是不是aaa是所有实例共享呢?

但是既然是常量,那么就无所谓共享不共享了。因为所有aaa都是相同的值。所以,aaa和bbb在使用上是完全一样的了。

只不过bbb是对象实例私有的,存放在堆空间的对象中,而aaa则是和一般的static一样存放在方法区中,以待对象的调用,加了一层限制,不允许调用的对象改变值罢了。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics