zoukankan      html  css  js  c++  java
  • java 对象 拆箱装箱 编译和反编译的验证

    创建对象

    package 创建对象的个数;

    public class main {
    public static void main(String[] agrs){
    Check c1=new Check();
    Check c2=new Check();
    Check c3=new Check();
    System.out.println("你已创建了"+c1.a+"个对象");
    }

    }
    class Check{
    static int a=0;
    //{
    // a=a+1;
    //}
    public Check(){
    a=a+1;
    }
    }

    一,验证的代码

    1,变量判等

    运行结果为:false

    ==”施加于原始数据类型变量时,是比较变量所保存的数据是否相等;当“==”施加于引用类型变量时,是比较这两个变量是否引用同一对象。

    2,初始化块,构造方法和字段的初始值哪一个说了算?

    运行结果为:

    100

    300

    总结:若是有参的构造方法,则输出带参数的值;若是无参的构造方法,则输出的值与初始化块和字段的额初始值的顺序有关;类的初始化块不接收任何的参数,而且只要创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

    3,静态方法只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

     可以在静态方法中添加类的对象的参数,在静态初始化块中创建类的对象,通过对象来访问实例数据。

     代码如下:

      public class text2{

     public static void main(String[] args){

      Foo obj1=new Foo();

      obj1.Foo1(obj1);

     }

    }

    class Foo{

        int field=100;

    public static void Foo1(Foo f){

    System.out.println("静态方法访问的实例数据为:"+f.field);;

    }

    static{

    Foo f1=new Foo();

    System.out.println("静态初始化块访问的实例数据为:"+f1.field);

          }

    public Foo(){

    }

    }

    运行结果

    静态初始化块访问的实例数据为:100

    静态方法访问的实例数据为:100

    4,装箱和拆箱

      代码和运行结果

     

    javap反编译class文件

     

    由图可知,装箱时调用Integer类的valueOf(int)方法,拆箱时调用的是Integer类的intValue()方法,装箱是将基本数据类型转换为包装器类型,拆箱是将包装器类型转换为基本数据类型。

    5,两对完全相同的整数,为何一个输出true,一个输出false

     代码及运行结果

     

    Javap反编译class

     

     

    由图可知,它调用了Integer类的valueOf()方法,通过JDK源码可以看出,在通过valueOf()方法创建Integer对象的时候,如果数值在【-128127】之间便返回指向已经存在的对象的引用,for则创建一个新的Integer对象,因为i1j1的值为100,所以会直接从擦车中取已经存在的对象,所以i1j1指向的是同一个对象,为i2j2指向的是不同的对象。

    6,创建对象的个数计算

    package 创建对象的个数;

    public class main {

    public static void main(String[] agrs){

    Check c1=new Check();

    Check c2=new Check();

    Check c3=new Check();

    System.out.println("你已创建了"+c1.a+"个对象");

    }

    }

    class Check{

        static int a=0;

    //{

    // a=a+1;

    //}

    public Check(){

    a=a+1;

    }

    }

    二,动手动脑

    1,以下代码为何无法通过编译?哪出错了?

    public class text2{

     public static void main(String[] args){

      Foo obj1=new Foo();

     }

    }

    class Foo{

    int value;

    public Foo(int initValue){

    value=initValue;

    }

    }

    因为用户自己定义了一个构造方法,所以系统不再提供默认的构造方法,所以类Foo中没有无参的构造方法,而新建立的对象没有参数。

    2,运行程序观察结果,总结“静态初始化块的执行顺序”

    运行结果如下:

    Root的静态初始化块

    Mid的静态初始化块

    Leaf的静态初始化块

    Root的普通初始化块

    Root的无参数的构造器

    Mid的普通初始化块

    Mid的无参数的构造器

    Mid的带参数构造器,其参数值:Java初始化顺序演示

    Leaf的普通初始化块

    执行Leaf的构造器

    总结:

    静态初始化块只在创建对象时执行一次;创建子类型的对象时,也会导致父类型的静态初始化块的执行;类的静态初始化块从父类开始先执行,然后执行子类的普通初始化块和构造方法。

  • 相关阅读:
    js实现深拷贝的几种方法
    禁止浏览器的默认行为 图片拖动 复制 剪切 右击
    祈祷奇迹,其实不如无尽的练习
    洛谷P4643 [国家集训队]阿狸和桃子的游戏 & 初赛心情
    Re:prime 关于质数的算法
    【洛谷有题】NOIP 2014 提高组初赛试题 订正 网络协议 检索/比较次数计算
    补码的快速计算
    2020洛谷初赛模拟 订正
    【洛谷有题】NOI 笔试题库(非初赛)订正
    树状数组小结
  • 原文地址:https://www.cnblogs.com/news1997/p/7697728.html
Copyright © 2011-2022 走看看