动手动脑——类与对象
1.
public class Test1 { public static void main(String []args) { Foo obj1 = new Foo(); Foo obj2 = new Foo(); System.out.println(obj1==obj2); } } class Foo{ int value = 100; }
输出结果:
引用代表地址,使用“==”判断两变量值是判断两个引用类型变量中保存到对象地址是否相同。
2.
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; } }
输出结果:
1.相同,这两个ojb1与obj2也是引用类型,“==”判断的是引用类型地址,地址不同所以是false
2.判断两个对象的字段值,可以“重写(override)” 基类的equals()方法。
动手动脑——1
为什么以下代码无法通过编译?哪里出错了?
public class Test{ public static void main(String [] args){ Foo obj1 = new Foo(); } } class Foo{ int value; public Foo(int intValue){ value = intValue; } }
错误:在Foo obj1 = new Foo();这一行中,Foo()调用的class Foo类,Foo()括号中须有具体的数值来使value = intValue.
进行试验——1
public class ObjectEquals { public static void main(String[] args) { InitiakzeBlockClass obj = new InitiakzeBlockClass(); System.out.println(obj.field); obj = new InitiakzeBlockClass(300); System.out.println(obj.field); } } class InitiakzeBlockClass{ { field = 200; } public int field = 100; public InitiakzeBlockClass(int value) { this.field = value; } public InitiakzeBlockClass() { } }
Java字段初始化的规律:
(1)执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。
(2)执行类的构造函数。
动手动脑——2
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) 创建子类型的对象时,也会导致父类型的静态初始化块的执行。
一个有趣的问题:
静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?
public class aaaa { static int n = 200; //静态变量 public static void main(String[] args) { New e = new New(); n = e.Shi(); //将实例变量赋值给静态变量 New.Jing(n); // } } class New{ int m = 100; //实例变量 int Shi(){ int x; x = m; return x;//实例函数,返回一个实例值 } static void Jing(int x){ System.out.println(x); //输出静态变量 } }
输出结果: