1. 关键字 new
在 Java 中,要创建任意类的对象,需要使用关键字 new。这个“魔法”词会请求 JVM:为新对象分配内存,并为其调用构造函数。
类比:
如果类是汽车的蓝图,那么 new 就是按照这张蓝图组装出真实汽车的工厂。
示例
Person vasya = new Person();
这里发生了什么:
- new Person() — 创建了一个新的 Person 类型的对象(调用了构造函数)。
- vasya — 变量,用来保存对所创建对象的引用。
这在内存中是什么样子
当你写下 Person vasya = new Person(); 时,内存中会为该对象的字段分配空间(例如,姓名和年龄),而变量 vasya 保存的则是这块内存区域的地址——也就是引用。
注意:
如果忘记写 new,变量就只是一个不指向任何对象的引用(null)。试图访问这种“空”对象的字段或方法会导致 NullPointerException。
2. 构造函数调用:如何工作?
构造函数是一个特殊的方法,它在创建对象时被调用,用于初始化对象的字段,使实例可以正常工作。
语法
ImyaKlassa imyaPeremennoy = new ImyaKlassa(argumenty);
- 如果类有带参数的构造函数,必须传入这些参数。
- 如果是无参构造函数(或默认构造函数),括号保持为空即可。
示例:带参数的构造函数
public class Person {
String name;
int age;
// 带参数的构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
创建对象:
Person petya = new Person("彼佳", 25);
"彼佳" 和 25 的值会进入新对象的 name 与 age 字段。
无参构造函数
public Person() {
this.name = "未命名";
this.age = 0;
}
现在可以这样写:
Person mysteryMan = new Person(); // name="未命名", age=0
3. 使用对象:字段与方法
创建对象之后,你可以通过点运算符(.)访问它的字段和方法:
petya.name = "彼得";
System.out.println(petya.name); // 彼得
petya.sayHello();
如果类中有如下方法:
public void sayHello() {
System.out.println("你好,我叫 " + name + "!");
}
那么调用 petya.sayHello(); 会输出:你好,我叫 彼得!
示例:完整的类
public class Person {
String name;
int age;
public Person(String name, int age) { // 构造函数
this.name = name;
this.age = age;
}
public void sayHello() { // 方法
System.out.println("你好,我叫 " + name + "!");
}
}
使用方式:
Person vasya = new Person("瓦夏", 30);
vasya.sayHello(); // 你好,我叫 瓦夏!
4. 引用变量:这是什么?
在 Java 中,类类型的变量是指向内存中对象的引用,而不是对象本身。
演示
Person vasya = new Person("瓦夏", 30);
Person anotherVasya = vasya;
现在 vasya 和 anotherVasya 都指向内存中的同一个对象。如果通过一个变量修改字段——另一个变量读取到的也会是被修改后的值:
anotherVasya.age = 31;
System.out.println(vasya.age); // 31
重要提示:
如果创建的是两个不同的对象,它们彼此独立:
Person petya = new Person("彼佳", 25);
Person masha = new Person("玛莎", 22);
petya.age = 99;
System.out.println(masha.age); // 22(没有改变!)
5. 示例:创建并使用多个对象
向应用中添加几个对象。假设我们有一个 Person 类,在 main 中创建几个人并输出他们的问候语。
Person 类
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("你好,我叫 " + name + ",我 " + age + " 岁!");
}
}
在 main 中的使用
public class Main {
public static void main(String[] args) {
Person vasya = new Person("瓦夏", 25);
Person petya = new Person("彼佳", 27);
vasya.sayHello(); // 你好,我叫 瓦夏,我 25 岁!
petya.sayHello(); // 你好,我叫 彼佳,我 27 岁!
// 对象独立性的演示:
vasya.age = 100;
vasya.sayHello(); // 你好,我叫 瓦夏,我 100 岁!
petya.sayHello(); // 你好,我叫 彼佳,我 27 岁!
}
}
程序输出:
你好,我叫 瓦夏,我 25 岁!
你好,我叫 彼佳,我 27 岁!
你好,我叫 瓦夏,我 100 岁!
你好,我叫 彼佳,我 27 岁!
6. 创建对象时的常见错误
错误 №1:忘记写 new
Person vasya;
vasya.name = "瓦夏"; // NullPointerException!
变量 vasya 没有指向任何对象(null)。必须使用 new 创建对象。
错误 №2:没有向构造函数传递参数
Person petya = new Person(); // 如果没有无参构造函数,将出现编译错误
如果类中只有带参数的构造函数,那么创建对象时必须提供这些参数。
错误 №3:以为变量保存的是对象本身
Person a = new Person("安雅", 20);
Person b = a;
b.age = 99;
System.out.println(a.age); // 99,因为 a 和 b 都是指向同一个对象的引用!
在 Java 中,类类型变量始终是引用,而不是对象本身。
错误 №4:修改了一个对象的字段,却以为另一个不会改变
Person x = new Person("X", 1);
Person y = x;
x.age = 42;
System.out.println(y.age); // 42
如果需要两个彼此独立的对象——请分别创建它们!
GO TO FULL VERSION