工做三年多了,作过很多的项目,越到最近越深深地感受到本身的基础薄弱,因此最近买了《java编程思想》。但愿经过此次的学习可以使本身有所收获。java
这也是我第一篇博客,以往只是看而没有本身写过,此次着重记录书本上习题的解答。编程
练习1:建立一个类,它包含一个未初始化的String引用。验证该引用被java初始化成了null。数组
package chapter5; public class Session1 { /** * 未初始化的变量会自动初始化为null */ String a; public static void main(String[] args) { Session1 session1 = new Session1(); System.out.println(session1.a); //“null” } }
练习2:建立一个类,它包含一个在定义是就被初始化了的String域,以及另外一个经过构造器初始化的String域。这两种方式有何差别?session
package chapter5; public class Session1 { /** * 会先初始化类中的变量 */ String b = "hello"; String c; public Session1() { System.out.println(b); /** * 后进行c的初始化 */ c = "world"; } public static void main(String[] args) { Session1 session1 = new Session1(); //在类初始化前会先初始化类中的变量 //“hello” } }
练习3:建立一个带默认构造器(即无参构造器)的类,在构造器中打印一条消息。为这个类建立一个对象。ide
package chapter5; public class Session2 { public Session2() { System.out.println("我是默认构造器"); } public static void main(String[] args) { Session2 session2 = new Session2(); //“我是默认构造器” } }
练习4:为前一个联系中的类添加一个重载构造器,令其接受一个字符串参数,并在构造器中把你本身的消息和接收参的参数一块儿打印出来。学习
package chapter5; public class Session2 { public Session2() { System.out.println("我是默认构造器"); } public Session2(String arg) { this(); System.out.println("我是重载有参构造器,我接收的参数为:"+arg); } public static void main(String[] args) { Session2 session2 = new Session2("hello world"); //“我是默认构造器” //“我是重载有参构造器,我接收的参数为:hello world” } }
练习5:建立一个名为Dog的类,它具备重载的bark()方法。此方法应根据不一样的基本数据类型进行重载,并根据被调用的版本,打印出不一样类型的狗吠(barking)、咆哮(howling)等信息。编写main()来调用全部不一样版本的方法。测试
package chapter5; public class Dog { void bark(String a){ System.out.println("barking:狗吠"); } void bark(Integer i){ System.out.println("howling:咆哮"); } public static void main(String[] args) { Dog dog = new Dog(); dog.bark("barking"); dog.bark(1); //barking:狗吠 //howling:咆哮 } }
练习6:修改前一个练习的程序,让两个重载方法各自接受两个类型不一样的参数,但两者顺序相反。验证其是否工做。this
package chapter5; public class Dog { /** * 参数顺序不一样也能够重载 * @param i * @param a */ void bark(Integer i,String a){ System.out.println("barking:狗吠"); } void bark(String a,Integer i){ System.out.println("howling:咆哮"); } public static void main(String[] args) { Dog dog = new Dog(); dog.bark(1,"barking"); dog.bark("barking",1); //barking:狗吠 //howling:咆哮 } }
练习7:建立一个没有构造器的类,并在main()中建立其对象,用以验证编译器是否真的自动加入了默认构造器。spa
package chapter5; public class Session7 { public static void main(String[] args) { Session7 session7 = new Session7(); } }
练习8:编写具备两个方法的类,在第一个方法内调用第二个方法两次:第一次调用时不使用this关键字,第二次调用时使用this关键字——这里只是为了验证它是起做用的,你不该该在实践中使用这种方式。命令行
package chapter5; public class TestThis { private void method1(){ method2(); /** * this指当前对象的引用 */ this.method2(); } private void method2(){ System.out.println("方法二"); } public static void main(String[] args) { TestThis testThis = new TestThis(); testThis.method1(); //方法二 //方法二 } }
练习9:编写具备两个(重载)构造器的类,并在第一个构造器中经过this调用第二个构造器。
package chapter5; public class Session4 { public Session4() { this("经过this调用有参构造器"); System.out.println("无参构造器"); } public Session4(String arg) { System.out.println(arg); } public static void main(String[] args) { Session4 session4 = new Session4(); //经过this调用有参构造器 //无参构造器 } }
5.5 清理:终结处理和垃圾回收
练习10:编写具备finalize()方法的类,并在方法中打印消息。在main()中为该类建立一个对象。试解释这个程序的行为。
package chapter5; public class TestFinalize { @Override protected void finalize() throws Throwable { System.out.println("回收前执行的方法"); } public static void main(String[] args) { TestFinalize finalize = new TestFinalize(); } }
finalize()方法不必定会执行。
练习11:修改前一个程序,让你的finalize()总会被调用。
package chapter5; public class TestFinalize { @Override protected void finalize() throws Throwable { System.out.println("回收前执行的方法"); } public static void main(String[] args) { TestFinalize finalize = new TestFinalize(); finalize = null; System.gc(); //回收前执行的方法 } }
练习12:编写名为Tank的类,此类的状态可使“满的”或“空的”。其终结条件是:对象被清理时必须处于空状态。编写finalize()以检验终结条件是否成立。在main()中测试Tank可能发生的几种使用方式。
package chapter5; public class Tank { private boolean full = true; @Override protected void finalize() throws Throwable { if(!full){ System.out.println("空了,不要了"); } } public static void main(String[] args) { Tank t = new Tank(); t = null; System.gc(); //此时状态是“满的”因此回收时不会执行输出 } }
package chapter5; public class Tank { private boolean full = true; @Override protected void finalize() throws Throwable { if(!full){ System.out.println("空了,不要了"); } } public static void main(String[] args) { Tank t = new Tank(); t.full = false; t = null; System.gc(); //状态是“空的” //回收时会输出 //空了,不要了 } }
练习14:编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另外一个在静态块中初始化。如今加入一个静态方法用以打印出两个字段值。请证实他们都会在被使用以前完成初始化动做。
package chapter5; public class Session7 { static String a = "hello world"; static String b; static { b = "hello world 2"; } public static void main(String[] args) { System.out.println(Session7.a); System.out.println(Session7.b); //hello world //hello world 2 } }
练习15:编写一个含有字符串域的类,并采用实例初始化方式进行初始化。
package chapter5; public class Session71 { String a; { a = "hello world"; } public static void main(String[] args) { Session71 session71 = new Session71(); System.out.println(session71.a); //hello world } }
练习16:建立一个String对象数组,并为每个元素都赋值一个String。用for循环来打印该数组。
package chapter5; public class Session8 { String[] strs = {"h","e","l","l","o"}; public static void main(String[] args) { Session8 session8 = new Session8(); for (String string : session8.strs) { System.out.print(string); } //hello } }
练习17:建立一个类,他有一个接受一个String参数的构造器。在构造阶段,打印该参数。建立一个该类的对象引用数组,可是不实际去建立对象赋值给该数组。当运行程序时,请注意来自对该构造器的调用中的初始化消息是否打印了出来。
package chapter5; public class Session81 { public Session81(String a) { System.out.println(a); } public static void main(String[] args) { Session81[] sss = new Session81[]{}; //不会进行打印输出 } }
练习18:经过建立对象赋值给引用数组,从而完成前一个练习。
package chapter5; public class Session81 { public Session81(String a) { System.out.println(a); } public static void main(String[] args) { Session81[] sss = new Session81[]{new Session81("1"),new Session81("2")}; //1 //2 } }
练习19:写一个类,他接受一个可变参数的String数组。验证你能够向该方法传递一个用逗号分隔的String列表,或是一个String[]。
package chapter5; public class Session82 { public Session82(String ...a) { for (String string : a) { System.out.println(string); } } public static void main(String[] args) { Session82 session82 = new Session82("a","b"); Session82 session821 = new Session82(new String[]{"a","b"}); } }
练习20:建立一个使用可变参数列表而不是普通的main()语法的main()。打印所产生的args数组的全部元素,并用各类不一样数量的命令行参数来测试它。
package chapter5; public class Session82 { public Session82(String ...a) { for (String string : a) { System.out.println(string); } } public static void main1(String...args) { Session82 session82 = new Session82("a","b"); Session82 session821 = new Session82(new String[]{"a","b"}); } }
练习21:建立一个enum,它包含纸币中最小面值的6种类型。经过values()循环并打印每个值及其ordinal();
package chapter5; public enum Session9 { YIMAO,YIKUAI,SHIKUAI,YIBAIKUAI //一毛,一块,十块,一百块 }
package chapter5; public class TestSession9 { public static void main(String[] args) { for (Session9 string : Session9.values()) { System.out.println(string); System.out.println(string.ordinal()); } //YIMAO //0 //YIKUAI //1 //SHIKUAI //2 //YIBAIKUAI //3 } }
练习22:在前面的例子中,为enum写一个switch语句,对于每个case,输出该特订货币的描述
package chapter5; public class TestSession9 { public static void main(String[] args) { TestSession9 session9 = new TestSession9(Session9.SHIKUAI); session9.descript(); } public TestSession9(Session9 session9) { this.session9 = session9; } private Session9 session9; void descript() { switch (session9) { case YIMAO: System.out.println("一毛"); break; case YIKUAI: System.out.println("一块"); break; case SHIKUAI: System.out.println("十块"); break; case YIBAIKUAI: System.out.println("一百块"); break; default: break; } } }