课后作业
Posted 什么名都不好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了课后作业相关的知识,希望对你有一定的参考价值。
课后作业一:
使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?
设计思路:定义类的构造函数时使静态变量i进行i++,即每构造一次就叠加一个构造的对象数。
程序流程图:
import java.util.Scanner; public class Test { static int i = 0; public Test(){ i++; } public static int getTimes(){ return i; } public static void main(String[] args) { int x = 1; Scanner con = new Scanner(System.in); for(; x != 0;){ System.out.print("构建个数(0退出):"); x = con.nextInt(); for(int t= 0; t < x; t++){ Testi g = new Test(); } System.out.println("程序已经创建对象的个数为:" + getTimes()); } } }
课后作业二:
1.这两种方式定义的变量是一样的吗?
Int value = 100;
MyClass obj = new MyClass();
不一样。
int “是原始数据类型”的变量。定义后,会马上给其分配内存。
MyClass “是对象变量”。声明一个对象类型变量时,实际没有创建一个对象,变量 = null。
2.对象变量可以用“==”判断两变量值是否相等吗?运行以下代码,得到什么结果?
不可以。判断的不是变量值。
public class Test{ public static void main(String[] args){ Foo obj1 = new Foo(); Foo obj2 = new Foo(); System.out.println(obj1 == obj2); } } class Foo{ int value = 100; }
结果:false
当“==”施加于引用类型变量时,比较的是两个变量是否引用同一个对象。
3.如何比较两个对象“内容”是否一样?
比较“字段值”。可以重写equals()方法。
public class ObjectEquals { public static void main(String[] args) { MyTestClass obj1 = new MyTestClass(100); MyTestClass obj2 = new MyTestClass(100); System.out.println(obj1 == obj2); System.out.println(obj1.equals(obj2)); } } class MyTestClass { public int Value; /*注意:只有参数类型为Object的,才是重写了Object的equals方法 参数类型为MyTestClass的,仅仅是Overload了equals方法。 @Override public boolean equals(Object obj) { return ((MyTestClass)obj).Value == this.Value; }
*/ public boolean equals(MyTestClass obj){ return obj.Value == this.Value; } public MyTestClass(int initValue){ Value = initValue; } }
结果:flase
true
4.总结一下,这个方法有那些“与众不同”之处?
public MyTestClass(int initValue){ Value = initValue; }
这个方法是类的构造方法。它有参数值。
5.以下代码为何无法通过编译?哪出错了?
public class Test{ public static void main(String[] args){ Foo obj1 = new Foo(); } } class Foo{ int value; public Foo(int initValue){ value = initValue; } }
Foo obj1 = new Foo()错误。
结论:如果类提供了一个自定义的构造方法,就将导致系统不再提供默认构造方法。所以,“Foo obj1 = new Foo();”中需要添加默认的参数。
6.如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
是“public int field = 100;”说了算。也就是谁比较靠后就是谁初始化起作用。执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
构造函数,类的初始化块不接收任何的参数,只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。
对象变量可以用“==”判断两变量值是否相等吗?运行以下代码,得到什么结果?
不可以。判断的不是变量值。
public class Test{ public static void main(String[] args){ GetField obj = new GetField(); System.out.println(obj.field); obj = new GetField(300); System.out.println(obj.field); } } class GetField{ { field = 200; } Public int field = 100; public GetField(int value){ this.field = value; } public GetField(){ } }
7.请运行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(); System.out.println("Mid的带参数构造器,其参数值:" + msg); } } class Leaf extends Mid{ static{ System.out.println("Leaf的静态初始化块"); } { System.out.println("Leaf的普通初始化块"); } public Leaf(){ super("Java初始化顺序演示"); System.out.println("执行Leaf的构造器"); } } public class TestStaticInitializeBlock{ public static void main(String[] args) { new Leaf(); } }
结论: 1.静态初始化块只执行一次。
2.创建子类型对象时,父类静态初始化块也执行。
8.静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
public class Test{ public static void main(String[] args){ System.out.println ("(静态变量)total_employees = "+Employee.clear()); Employee e = new Employee(); System.out.print("(实例变量)name = "+e.name); } } class Employee{ String name = "2"; static int total_employees = 0; static int clear(){ return total_employees; } static void clear2(){ } }
9. 输出诡异的结果,原因何在?
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); } Integer cache类的实现: private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer\'s autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
上面的代码中i1和j1的数值为100,因此会直接从cache中取已经存在的对象,所以i1和j1指向的是同一个对象,而i2和j2则是分别指向不同的对象。所以输出不同。
以上是关于课后作业的主要内容,如果未能解决你的问题,请参考以下文章