java-03-动手动脑
1.
问题:这两种方式定义的变量是一样的吗?
早期我们经常这样定义变量
int value=100;
前面的示例中这样定义变量
MyClass obj = new MyClass();
回答:一般情况是一样的,都是类的实例化,一个是简便写法,一个是正常定义对象的方式。
2.
问题:对象变量也可以使用“==”判断两变量值是否相等吗?
回答:如果两个对象变量指向同一个对象时,可以用“==”判断两变量是否相等。
Java中如果要比较对象的“内容”,可以通过重写基类的equals();除了重写基类的equals方法,还可以“重载(overload)”equals( )方法;
3
问题:请总结一下,这个方法有哪些“与众不同之处”,你能列出几条?
回答:1.方法名是类名
2.没有返回值类型
4.
问题:以下代码为何无法通过编译?哪儿出错了?
回答:Foo类写了一个有参的构造函数,但没有无参的构造函数。这时候系统不会调用默认的构造函数,
而主函数中使用了无参的构造函数,所以产生了错误。即如果类提供了一个自定义的构造方法,将导致
系统不再提供默认构造方法。
5.
问题:如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?
执行代码:
public class InitializeBlockDemo { /** * @param args */ 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(){ } }
结果截图:
如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,构造函数说了算。
6.
自行总结Java字段初始化的规律:
1执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
2执行类的构造函数。
3类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”.
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调用同一类中重载的构造器 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创建子类型的对象时,也会导致父类型的静态初始化块的执行。
8
问题:静态方法中只允许访问静态数据,那么,如何在静态方法中访问类
的实例成员(即没有附加static关键字的字段或方法)?请编写代码验证你的想法。
执行代码:
package 列子;
public class JingtaiDiaoyong {
int a = 3;
static int b=4;
public static void ceshi()
{
System.out.println("非静态变量a=" + new JingtaiDiaoyong().a);
System.out.println("静态变量b=" + b);
}
public static void main(String[] args)
{
JingtaiDiaoyong.ceshi();
JingtaiDiaoyong j1 = new JingtaiDiaoyong();
System.out.println("a=" + j1.a);
}
}
结果截图:
静态方法中访问类的实例成员先进行类的实例化。
9.
问题:Integer类的装箱和拆箱到底是怎样实现的?
在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。
因此可以用一句话总结装箱和拆箱的实现过程:
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 intValue方法实现的.
10.
问题:代码(StrangeIntegerBehavior.java)输出诡异的结果,原因何在?
代码:
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); } }
结果截图:
integer实现过程中,int型范围在-128到127之间,在这之间,反复使用integer,都是重复上次的对象,都是一样的,
但超出范围,反复使用时,会生成新的对象,与上一次不会相等。