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对象的时候,如果数值在【-128,127】之间便返回指向已经存在的对象的引用,for则创建一个新的Integer对象,因为i1和j1的值为100,所以会直接从擦车中取已经存在的对象,所以i1和j1指向的是同一个对象,为i2和j2指向的是不同的对象。
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的构造器
总结:
静态初始化块只在创建对象时执行一次;创建子类型的对象时,也会导致父类型的静态初始化块的执行;类的静态初始化块从父类开始先执行,然后执行子类的普通初始化块和构造方法。