类的加载与反射之代码演示

看下面代码请参考上一篇《类的加载与反射与反射》
例子一:

class FinalTest{
    //编译时候直接将常量yeshiwu放入常量池中,本质上并没有直接引用到定义常量类的初始化
    public static final String str="yeshiwu";
    //编译的时候就可以确定为2,所以不会对类进行初始化
    public static final int x=6/3;
    //编译的时候不能确定,运行的时候才能确定,所以会对类进行初始化
    public static final int x2=new Random().nextInt(100);
    static{
        System.out.println("FinalTest static block");
    }
}

public class Test2 {
    public static void main(String[] args){
        System.out.println(FinalTest.x);
        System.out.println(FinalTest.str);
        System.out.println(FinalTest.x2);
    }
}

2
yeshiwu
FinalTest static block
41

当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。

例子二:

class Parent{
    static int a=3;
    static {
        System.out.println("parent static block");
    }
}

class Child extends Parent{
    static int b=4;
    static {
        System.out.println("Child static block");
    }
}

public class Test4 {
    static {
        System.out.println("Test4 static block");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println(Child.b);
    }
}

Test4 static block
parent static block
Child static block
4

这里先加载主类,static静态初始化执行,然后初始化子类的时候会先去加载父类。

例子三:

class Parent2{
    static int a=3;
    static{
        System.out.println("Parent2 static block");
    }
}

class Child2 extends Parent2{
    static int b=4;
    static{
        System.out.println("Child2 static block");
    }

}

public class Test5 {
    static{
        System.out.println("Test5 static block");
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Parent2 parent2;
        System.out.println("-------------");
        parent2=new Parent2();
        System.out.println(Parent2.a);
        System.out.println(Child2.b);
    }   
}
Test5 static block
-------------
Parent2 static block
3
Child2 static block
4

先加载父类,当再加载子类的时候便不会再去加载子类。

例子四

class Parent3{
    static int a=3;
    static{
        System.out.println("Parent3 static block");
    }
    static void doSomething(){
        System.out.println("doSomething");
    }
}

class Child3 extends Parent3{
    //Child3没有被初始化,因为Child3.a不是对Child3的主动使用,而是对Parent的主动使用
    static{
        System.out.println("Child3 static block");
    }
}

public class Test6 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Parent3[] parents = new Parent3[10];
        Child3.a=4;
        System.out.println(Child3.a);
        Child3.doSomething();
    }
}

通过子类来引用父类的静态字段,不会导致子类初始化。通过数组来定义类,也不会触发此类的初始化。

顺便在这里提一下final修饰的变量:

public static void main(String[] args) {
        String a = "hello2"; 
        final String b = "hello";
        String d = "hello";
        String e = d + 2;
        String c = b + 2; 

        String str1="aaa";
        String str2="aaa";

        String str3=str1+"bbb";
        String str4="aaabbb";

        final String str="bbb";
        String str5=str1+str;
        String str6="aaa"+str;


        //true  当str1和str2代表字符串一样时string会指向同一个地方
        System.out.println(str1==str2);
        //str3和str4是由链接来形成的,指向的根本不是同一个地址
        System.out.println(str3==str4);//false
        //b被final修饰,被当做编译器常量,使用b的地方会直接将b替换为它的值,和str1==str2道理一样
        System.out.println((a == c));//true
        System.out.println((a == e));//false

    }

final和static的区别
static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。看下面这个例子:

class MyClass {
    public final double i = Math.random();
    public static double j = Math.random();
}
public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyClass myClass1 = new MyClass();
        MyClass myClass2 = new MyClass();
        System.out.println(myClass1.i);
        System.out.println(myClass1.j);
        System.out.println(myClass2.i);
        System.out.println(myClass2.j);
    }
}

static 修饰的变量j,第一次初始化MyClass的时候就已经给赋值j赋值了,第二次初始化的时候不会再管j了,所以第二次和第一次j的值是一样的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值