1.请输入以下代码,得到什么结果
public class Test { public static void main(String[] args) { Foo obj1 = new Foo(); } } class Foo{ int value; public Foo(int initValue){ value = initValue; } }
错误信息为:“The constructor Foo() is undefined”(构造函数Foo()未定义)
思考:
Foo类写了一个有参的构造函数,但没有无参的构造函数。这时候系统不会调用默认的构造函数,
而主函数中使用了无参的构造函数,所以产生了错误。即如果类提供了一个自定义的构造方法,将导致
系统不再提供默认构造方法。
2.如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,构造函数说了算。
public class Test { public static void main(String[] args) { InitializeBlockClass obj = new InitializeBlockClass(123); System.out.println("field:" + obj.field); } } class InitializeBlockClass{ public int field = 100; public InitializeBlockClass(int value){ System.out.println("field:" + this.field); this.field = value; } { field = 200; } }
结果: 先200 后123
所以最终都是由构造函数说了算。
3.请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。
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 TestStaticInitializeBlock { public static void main(String[] args) { new Leaf(); } }
1静态初始化块只执行一次。
2创建子类型的对象时,也会导致父类型的静态初始化块的执行。
代码(StrangeIntegerBehavior.java)输出诡异的结果,原因何在?
4.
public class StrangeIntegerBehavior { public static void main(String[] args) { Integer i1=100; Integer j1=100; System.out.println(i1==j1); Integer i2=129; Integer j2=129; System.out.println(i2==j2); } }
ture
false
在通过valueof方法创建Integer类型对象时,取值范围为[-128,127],数值在这个区间里,指针指向IntegerCache.cache中已经存在的对象引用,当数值超出这个范围,就会创建一个新的对象。而对对象使用“==”是判断两个对象是否是同一个,所以i1 == j1,i2 != j2。