关于本次课堂代码的练习
Posted yxsz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于本次课堂代码的练习相关的知识,希望对你有一定的参考价值。
(1)对象变量的判等
public class demo01 { static class Foo{ int value = 100; } public static void main(String[] args) { Foo obj1 = new Foo(); Foo obj2 = new Foo(); System.out.println(obj1 == obj2); } }
如代码可见,obj1和obj2是否为等?
答案如下
为什么会出现false呢?原因在于,当你将“==”作用于引用类型变量时,比较的是这两个变量是否引用于同一对象。而引用代表地址,所以本质上上述代码比较的是地址值,所以出现false也是合情合理的了。
(2)自定义构造方法和默认构造方法
public class demo01 { static class Foo{ int value; public Foo(int initvalue) { value = initvalue; } } public static void main(String[] args) { Foo obj = new Foo(); } }
如图代码。
此代码是无法编译的,因为编译器会报错。错误点在于:
在没有手动输入一个类的构造方法时,编译器会自动提供一个无参的构造方法。而上述代码很明显,编程者手动写了一个构造方法Foo(int initvalue),这是一个有参构造方法,而编译器检测到这个方法后,就不再提供无参构造方法。所以,当编程者实例化无参构造方法时,系统就会报错了。解决方案如下:
public class demo01 { static class Foo{ int value; public Foo(int initvalue) { value = initvalue; } } public static void main(String[] args) { int initvalue = 0; Foo obj = new Foo(initvalue); } }
这样的程序是可执行的。
(3)关于类的初始化块
public class demo01 { public static void main(String[] args) { InitializeBlockClass obj=new InitializeBlockClass(); System.out.println(obj.field); obj=new InitializeBlockClass(300); System.out.println(obj.field); } } class InitializeBlockClass{ //下面这句在初始化块之前与之后,会影响到field字段的初始值 //public int field=100; { field=200; } public int field=100; public InitializeBlockClass(int value){ this.field=value; } public InitializeBlockClass(){ } }
如图代码
当一个类中如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
上述代码运行结果可见:
所以,根据这道题结论可知:
1、执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
2、执行类的构造函数。
(4)静态初始化块的执行顺序
package Demo01; class Root { static{ System.out.println("Root的静态初始化块"); } { System.out.println("Root的普通初始化块"); } public Root() { System.out.println("Root的无参数的构造器"); } } class Mid extends Root { static{ System.out.println("Mid的静态初始化块"); } { System.out.println("Mid的普通初始化块"); } public Mid() { System.out.println("Mid的无参数的构造器"); } public Mid(String msg) { //通过this调用同一类中重载的构造器 this(); System.out.println("Mid的带参数构造器,其参数值:" + msg); } } class Leaf extends Mid { static{ System.out.println("Leaf的静态初始化块"); } { System.out.println("Leaf的普通初始化块"); } public Leaf() { //通过super调用父类中有一个字符串参数的构造器 super("Java初始化顺序演示"); System.out.println("执行Leaf的构造器"); } } public class demo01{ public static void main(String[] args) { new Leaf(); } }
- 静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;
- 非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;
- 非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
- 静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
- 非静态初始化块可以针对多个重载构造函数进行代码复用。
(5)在静态方法中访问类的实例成员
package Demo01; public class demo01 { int x = 3;//类的实例变量,初始化值为3 static int y = 4;//类的静态变量,初始化值为4 public static void method()//静态方法 { System.out.println("实例变量x = " + new demo01().x);//在静态方法中访问类的实例变量需首先进行类的实例化 System.out.println("静态变量y = " + y);//在静态方法中可直接访问类的静态变量 } public static void main(String[] args) { demo01.method(); demo01 ex = new demo01(); System.out.println("x = " + ex.x); } }
结果:
以上是关于关于本次课堂代码的练习的主要内容,如果未能解决你的问题,请参考以下文章