一、课件代码验证
1. 自定义类与对象使用代码
// 自定义类 MyClass
class MyClass {// 私有字段private int value;// 公有字段public String Information;// 方法:设置value值public void setValue(int value) {this.value = value;}// 方法:获取value值public int getValue() {return this.value;}// 自定义方法public void myMethod(String str) {System.out.println("传入的字符串:" + str);}
}// 测试类
public class ClassAndObjectTest {public static void main(String[] args) {// 创建类的实例,定义对象变量引用实例MyClass obj = new MyClass();// 调用类的公有方法obj.myMethod("Hello");// 给属性赋值obj.setValue(100);// 输出属性当前值System.out.println(obj.getValue());// 直接访问对象公有字段obj.Information = "Information";// 输出公有字段当前值System.out.println(obj.Information);}
}
- 验证结果:运行后依次输出“传入的字符串:Hello”“100”“Information”,符合预期,表明对象创建、方法调用及字段访问正常。
2. 对象判等代码
// 定义Foo类
class Foo {int value = 100;
}// 测试类
public class Test {public static void main(String[] args) {Foo obj1 = new Foo();Foo obj2 = new Foo();System.out.println(obj1 == obj2); }
}
- 验证结果:输出“false”。因“==”用于引用类型时比较对象地址,obj1和obj2是两个不同对象,地址不同,结果正确。
3. 重写equals方法代码
// 自定义类 MyTestClass
class MyTestClass {public int Value;// 构造方法public MyTestClass(int initValue) {Value = initValue;}// 重写equals方法@Overridepublic boolean equals(Object obj) {// 实际开发中需添加参数有效性检测,此处为简化示例return ((MyTestClass) obj).Value == this.Value;}
}// 测试类
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)); }
}
- 验证结果:依次输出“false”“true”。“==”比较地址不同为false,重写后的equals比较字段值相同为true,符合逻辑。
4. 构造方法相关代码(编译错误示例)
// 测试类
public class Test {public static void main(String[] args) {Foo obj1 = new Foo(); }
}class Foo {int value;// 自定义带参构造方法public Foo(int initValue) {value = initValue;}
}
- 验证结果:编译报错。因类自定义带参构造方法后,系统不再提供默认无参构造方法,创建对象时调用无参构造方法会失败,需手动添加无参构造方法才能编译通过。
5. 类字段初始化顺序代码
// 定义初始化块类
class InitializeBlockClass {// 字段初始值public int field = 100;// 初始化块{field = 200;}// 带参构造方法public InitializeBlockClass(int value) {this.field = value;}// 无参构造方法public InitializeBlockClass() {}
}// 测试类
public class TestInitialize {public static void main(String[] args) {InitializeBlockClass obj = new InitializeBlockClass();System.out.println(obj.field); obj = new InitializeBlockClass(300);System.out.println(obj.field); }
}
- 验证结果:依次输出“200”“300”。先执行字段初始值(100),再执行初始化块(200),最后执行构造方法(无参时保持200,带参时改为300),符合初始化顺序规则。
6. 装箱拆箱代码
// 测试类
public class BoxAndUnbox {public static void main(String[] args) {int value = 100;Integer obj = value; int result = obj * 2; System.out.println(result); }
}
- 验证结果:输出“200”。装箱时自动调用
Integer.valueOf(100)
,拆箱时自动调用obj.intValue()
,运算正常,结果正确。
7. Integer诡异特性代码
// 测试类
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); }
}
- 验证结果:依次输出“true”“false”。Integer缓存-128到127之间的对象,100在缓存范围内,i1和j1引用同一对象;129超出范围,创建新对象,地址不同。
二、动手动脑问题整合
1. 问题:引用类型变量与原始数据类型变量的区别
- 问题描述:早期定义变量如
int value=100
,示例中定义MyClass obj = new MyClass()
,这两种变量是否一样?
- 分析与解答:不一样,核心区别如下:
- 内存分配:原始数据类型变量声明时直接分配内存并存储值;引用类型变量声明时仅存储对象地址,不直接创建对象,默认值为null。
- 数据存储:原始数据类型变量存储具体数值;引用类型变量存储对象在内存中的地址,通过地址访问对象。
2. 问题:对象变量未初始化编译错误原因
- 问题描述:代码
public class Test {public static void main(String[] args){MyClass obj;System.out.println(obj.toString());}}
为何无法通过编译?
- 分析与解答:Java要求变量必须显式初始化。对象变量obj仅声明未赋值,未引用任何对象,也未设为null,编译器无法确定其状态,故编译报错,需改为
MyClass obj = null
(虽调用方法会抛空指针异常,但可通过编译)。
3. 问题:静态方法中访问类实例成员的方式
- 问题描述:静态方法只允许访问静态数据,如何在静态方法中访问类的实例成员?
- 分析与解答:需在静态方法中创建类的实例,通过实例访问实例成员,代码示例如下:
class MyClass {// 实例字段public int value;// 静态方法public static void staticMethod() {// 创建类的实例MyClass obj = new MyClass();// 通过实例访问实例成员obj.value = 100;System.out.println(obj.value);}
}public class TestStatic {public static void main(String[] args) {MyClass.staticMethod(); }
}
- 运行结果:输出“100”,表明通过创建实例可在静态方法中访问实例成员。
4. 问题:静态初始化块的执行顺序
- 问题描述:运行TestStaticInitializeBlock.java示例,总结静态初始化块的执行顺序。
- 分析与解答:
- 静态初始化块仅执行一次,无论创建多少个类的对象,只在类第一次加载时执行。
- 创建子类型对象时,会先执行父类型的静态初始化块,再执行子类型的静态初始化块。
- 示例代码(父类与子类):
// 父类
class Parent {static {System.out.println("父类静态初始化块");}
}// 子类
class Child extends Parent {static {System.out.println("子类静态初始化块");}
}// 测试类
public class TestStaticInitializeBlock {public static void main(String[] args) {Child child1 = new Child();Child child2 = new Child();}
}
- 运行结果:仅输出“父类静态初始化块”“子类静态初始化块”,且只输出一次,验证上述执行顺序。
- 问题:总结构造方法的“与众不同之处”
- 问题描述:分析代码
class MyTestClass {public int Value;public MyTestClass(int initValue) {Value = initValue;}}
中构造方法的特殊之处。
- 分析与解答:
- 方法名与类名完全相同,无返回值(包括void)。
- 对象创建时自动调用,用于初始化对象的字段和执行初始化操作。
- 若类未定义构造方法,系统自动提供无参默认构造方法;若自定义构造方法,默认构造方法失效。
- 支持重载,可通过不同参数列表定义多个构造方法,且构造方法间可通过
this()
相互调用。