一、课件代码验证
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方法
@Override
public 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()相互调用。