1.创建一个类, 它包含一个未初始化的String引用。验证该引用被Java初始化成了null
package net.mindview.initialization; public class Test1 { public String str; public static void main(String[] args) { Test1 t = new Test1(); System.out.println(t.str); } }
返回结果
null
2.创建一个类, 它包含一个在定义时就被初始化了的String域, 以及另一个通过构造器初始化的String域, 这两种方式有何差异?
package net.mindview.initialization; public class Test2 { public String str1 = "abc"; public String str2; public Test2(){ System.out.println(str1); System.out.println(str2); this.str2 = "def"; System.out.println(str1); System.out.println(str2); } public static void main(String[] args) { Test2 t = new Test2(); } }
运行结果:
abc null abc def
结论: 定义是就被初始化的str1只被赋值一次, 而定义时未被初始化str2被赋值了两次, 第一次是null,第二次是构造器赋值.
3.创建一个带默认构造器的类, 在构造器中打印一条消息. 为这个类创建一个对象.
package net.mindview.initialization; public class Test3 { public Test3(){ System.out.println("默认构造器"); } public static void main(String[] args) { Test3 t = new Test3(); } }
4.为前一个联系中的类添加一个冲在构造器,令其接受一个字符串参数,并在构造器中吧自己的消息和接受的参数一起打印出来.
package net.mindview.initialization; public class Test3 { public Test3(){ System.out.println("默认构造器"); } public Test3(String str){ System.out.println("有一个参数的构造器"); System.out.println(str); } public static void main(String[] args) { Test3 t = new Test3(); Test3 t2 = new Test3("hello"); } }
5.创建一个名为dog的类, 它具有重载的bark()方法, 此方法根据不同的基本数据类型重载, 并根据被调用的版本,打印出不同类型的狗吠(barking),咆哮(howling)等信息.编写main()来调用所有不同版本的方法
package net.mindview.initialization; public class Dog { public void bark(){ System.out.println("barking"); } public void bark(String paoxiao){ System.out.println("howling"); } public static void main(String[] args) { Dog dog1 = new Dog(); dog1.bark(); dog1.bark("paoxiao"); } }
6.(略)
7.(略)
8.编写具有两个方法的类,在第一个方法内调用第二个方法两次:第一次调用时不使用this关键字,第二次调用时使用this关键字-- * 这里只是为了验证它是起作用的,你不应该在实践中使用这种方法。
package net.mindview.initialization; public class Test8 { public void method1(){ System.out.println("1"); method2().method2(); } public Test8 method2(){ System.out.println("2"); return this; } public static void main(String[] args) { Test8 t = new Test8(); t.method1(); } }
9.略)
10.编写具有finalize()方法的类,并在方法中打印消息,在main()中为该类创建一个对象,试解释这个程序的行为。
package net.mindview.initialization; public class Test10 { @Override protected void finalize() throws Throwable { System.out.println("调用了finalize方法"); super.finalize(); } public static void main(String[] args) { Test10 t = new Test10(); t = null; System.gc(); Test10 t1 = new Test10(); t1 = null; System.gc(); } }
即便我手动调用垃圾回收处理了, 但finalize方法也不是每次都会被调用. 也就是说虽然我手动触发垃圾回收, 但实际上, 并没有真的触发垃圾回收. 下面这篇文章就解释原因:
http://blog.csdn.net/yewei02538/article/details/52386642
11.修改前一个练习的程序,让你的finalize()总会被调用。
- 如何才能让finzlize()总会被调用呢? 手动调用system.runFinalization()
package net.mindview.initialization; public class Test10 { @Override protected void finalize() throws Throwable { System.out.println("调用了finalize方法"); super.finalize(); } public static void main(String[] args) { Test10 t = new Test10(); t = null; System.gc(); Test10 t1 = new Test10(); t1 = null; System.gc(); System.runFinalization(); } }
12.(4)编写名为Tank的类,此类的状态可以是“满的”或“空的”。其终结条件是:对象被清理时必须处于空状态。 * 请编写finalize()以检验终结条件是否成立,在main()中测试Tank可能发生的几种使用方式
package net.mindview.initialization; public class Tank { public String state = "empty"; public Tank(String state){ this.state = state; } void clear(){ this.state = "empty"; } @Override protected void finalize() throws Throwable { System.out.println("------finalize---------"); if(!state.equals("empty")){ System.out.println("Error!!Tank未被清空"); } super.finalize(); } public static void main(String[] args) { Tank tank1 = new Tank("full"); tank1.clear(); System.gc(); System.runFinalization(); Tank tank2 = new Tank("full"); tank1 = null; tank2 = null; System.gc(); System.runFinalization(); } }
这里需要将tank1和tank2手动置为空. 否则垃圾回收机制会将其标记, 然后再下一个周期
清除.
13.(略)
14.编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另一个在静态块中初始化。现在,加入一个静态方法用以打印出两个字段值。请证明它们都会在被使用之前完成初始化动作。
package net.mindview.initialization; public class Test14 { public static String str1 = "abc"; public static String str2; static { str2 = "def"; } public static void print(){ System.out.println("str1 :"+ str1); System.out.println("str2 :"+ str2); } public static void main(String[] args) { print(); } }
15.编写一个含有字符串域的类,并采用实例初始化方式进行初始化。
package net.mindview.initialization; public class Test14 { public static String str1 = "abc"; public static String str2; public String str3; //静态成员初始化 static { str2 = "def"; //str3 = "aaa"; //报错 } //非静态成员初始化 { str3 = "aaa"; str2 = "mmm";//也可以给静态成员初始化 } public static void print(){ System.out.println("str1 :"+ str1); System.out.println("str2 :"+ str2); } public static void main(String[] args) { Test14 t = new Test14(); print(); System.out.println("str3 :"+ t.str3); } }
16.(略)
17.创建一个类,他有一个接受一个String参数的构造器。在构造阶段,打印该参数。创建一个该类的对象引用数组,但是不实际去创建对象赋值给该数组。当运行程序时,请注意来自对该构造器的调用中的初始化消息是否打印了出来
package net.mindview.initialization; public class Test17 { public Test17(String str){ System.out.println(str); } public static void main(String[] args) { Test17[] tt = null; } }
只有实例化的时候才会调用构造方法
18.通过创建对象赋值给引用数组,从而完成前一个练习。
package net.mindview.initialization; import java.util.Random; public class Test17 { public Test17(String str){ System.out.println(str); } public static void main(String[] args) { Random rand = new Random(); Test17[] tt = new Test17[rand.nextInt(100)]; for(int i=0;i<tt.length; i++){ tt[i] = new Test17(""+i); } } }
19.写一个类,他接受一个可变参数的String数组,验证你可以向该方法传递一个用逗号分隔的String列表,或是一个String[]。
package net.mindview.initialization; public class Test19 { public void print(String ...strings){ for(String str: strings){ System.out.print(str); } System.out.println(); } public static void main(String[] args) { Test19 t = new Test19(); t.print("aaa", "bbb", "ccc"); t.print(new String[]{"d","e","f"}); } }
20.创建一个使用可变参数列表而不是普通的main()语法的main()。打印所产生的args数组的所有元素,并用各种不同数量的命令行参数来测试它。
package net.mindview.initialization; public class Test19 { public static void main(String ...args){ for(String arg: args){ System.out.println(arg); } } }
21.创建一个enum,它包含纸币中最小面值的6种类型。通过values()循环并打印每一个值及其ordinal()
package net.mindview.initialization; enum Money{ ONE, TWO, FIVE, TEN, FIVTY, HUNDRED } public class Test21 { public static void main(String[] args) { for(Money m : Money.values()){ System.out.println(m + " " + m.ordinal()); } } }
22.在前面的例子中,为enum写一个switch语句,对于每一个case,输出该特定货币的描述。
package net.mindview.initialization; enum Money{ ONE, TWO, FIVE, TEN, FIFTY, HUNDRED } public class Test22 { Money value; public Test22(Money value){ this.value = value; } public void printValue(){ switch(value){ case ONE: System.out.println("1元面值"); break; case TWO: System.out.println("2元面值"); break; case FIVE: System.out.println("5元面值"); break; case TEN: System.out.println("10元面值"); break; case FIFTY: System.out.println("50元面值"); break; case HUNDRED: System.out.println("100元面值"); break; } } public static void main(String[] args) { Test22 t = new Test22(Money.ONE); Test22 t2 = new Test22(Money.TWO); Test22 t3 = new Test22(Money.HUNDRED); t.printValue(); t2.printValue(); t3.printValue(); } }