Java构造方法详解

July 08, 2025 / Eila / 12阅读 / 0评论/ 分类: 笔记

问题

问题一:

构造对象,声明时,如StxStu s1 = StxStu(); ,前面的StxStu要和class 后面的类名称保持一致吗?

在 Java 中构造对象时,声明类型(等号左边的 StxStu)必须与类名(class StxStu)完全一致,包括大小写。这是 Java 的语法硬性要求。

以下是详细说明:

1. 基本语法规则

// 类定义
public class StxStu {  // 类名是 StxStu
    // 属性和方法...
}

// 正确构造方式
StxStu s1 = new StxStu();  // 前后 StxStu 必须完全一致

部分

要求

声明类型

必须与类名完全一致(StxStu

构造方法调用

new 后的类名必须完全匹配(StxStu()

大小写敏感

stxstu/STXSTU 等不同大小写形式会被视为不同标识符,导致编译错误

2. 常见错误示例

❌ 错误1:大小写不一致

java

Stxstu s1 = new StxStu();  // 编译错误:找不到符号 Stxstu

❌ 错误2:拼写不一致

java

StxStudent s1 = new StxStu();  // 编译错误:类型不兼容

❌ 错误3:缺少 new 关键字

java

StxStu s1 = StxStu();  // 编译错误:找不到符号 StxStu()

3. 特殊情况处理

(1) 使用父类/接口声明

class Animal {}
class Cat extends Animal {}

// 合法:用父类类型声明
Animal a = new Cat();  // 多态

(2) 使用 var(Java 10+)

var s1 = new StxStu();  // 自动推断类型为 StxStu

(3) 构造方法重载

public class StxStu {
    public StxStu() {}          // 无参构造
    public StxStu(String name) {} // 带参构造
}

// 根据参数选择不同构造方法
StxStu s1 = new StxStu();
StxStu s2 = new StxStu("张三");

4. 完整正确示例

// 定义类
public class StxStu {
    private String name;
    
    // 构造方法
    public StxStu() {
        this.name = "匿名";
    }
    
    public StxStu(String name) {
        this.name = name;
    }
    
    public void sayHello() {
        System.out.println("我是" + name);
    }
}

// 使用类
public class Main {
    public static void main(String[] args) {
        // 正确构造对象
        StxStu s1 = new StxStu();       // 前后类名一致
        StxStu s2 = new StxStu("李四"); // 带参构造
        
        s1.sayHello();  // 输出:我是匿名
        s2.sayHello();  // 输出:我是李四
    }
}


5. 关键记忆点

  1. 严格一致:声明类型、new 后的类名、实际类定义三者必须完全一致

  2. 大小写敏感:Java 是大小写敏感语言,StxStustxstu

  3. 构造方法不是普通方法:不能直接写 StxStu(),必须配合 new 使用

  4. 多态例外:当使用父类/接口声明时,右侧可以是子类实现(但子类名仍需正确)

提示:如果遇到类似错误,优先检查:

  1. 类名拼写和大小写

  2. 是否漏写 new 关键字

  3. 类文件是否在正确路径(编译通过需要)

代码示例

public class Point {
    double x,y;
     public Point(double _x,double _y){
        x = _x;
        y = _y;
    }

    public double getDistance(Point p){
        double d = Math.sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
        return d;
    }


    public static void main(String[] args) {
        Point p1 = new Point(3.0,4.0);
        Point origin = new Point(.0,0.0);
        System.out.println(origin.getDistance(p1));
    }
}

问题二:

public Point(double _x,double _y){
        x = _x;
        y = _y;
    }

这段代码是 Java 中的一个构造方法(Constructor),用于创建 Point 类的对象时初始化对象的属性。我来用简单易懂的方式解释:


构造方法的基本作用

  1. 对象出生时的"初始化":就像新生儿要登记姓名、出生时间一样,构造方法在对象创建时给它设置初始属性值

  2. 强制要求提供必要信息:这里要求创建 Point 对象时必须提供 x 和 y 坐标


逐行解析

java

public Point(double _x, double _y) {  // 构造方法声明
    x = _x;  // 把传入的_x值赋给当前对象的x属性
    y = _y;  // 把传入的_y值赋给当前对象的y属性
}

部分

说明

public Point

方法名必须与类名完全相同,且没有返回类型(连void都不写)

(double _x, double _y)

要求创建对象时必须传入两个double参数(坐标值)

x = _x;

将参数 _x 的值赋给当前对象的属性 xthis.x 的简写)

y = _y;

将参数 _y 的值赋给当前对象的属性 y


实际使用示例

当这样创建对象时:

Point p = new Point(3.0, 4.0);

内存中的效果:

p → {
    x: 3.0  // 来自第一个参数
    y: 4.0  // 来自第二个参数
}

为什么参数名用 _x_y

这是一种命名约定,目的是:

  1. 区分参数和属性:如果直接写 x = x; 会产生歧义

  2. 更清晰的代码:一看就知道 _x 是参数,x 是成员变量

(也可以这样写,效果相同):

public Point(double x, double y) {
    this.x = x;  // this.x 表示当前对象的属性
    this.y = y;
}

类比理解

把构造方法想象成点对象的出生证明办理处

  • 办理要求:必须提供横纵坐标(_x, _y

  • 办理过程:把提供的坐标登记到新对象的属性中(x = _x

  • 产出结果:一个带有指定坐标的Point对象


如果没有构造方法会怎样?

Java会提供一个默认的无参构造方法,但这样创建的点对象坐标会是默认值0:

java

Point p = new Point();  // 如果没定义构造方法可以这样,但x,y都是0.0
// 但因为我们定义了构造方法,这样写会报错

关键点总结

  1. 构造方法特点

    • 方法名 = 类名

    • 没有返回类型

    • new 时自动调用

  2. 这个构造方法的作用

    • 强制要求创建Point时必须提供坐标

    • 把提供的坐标值赋给新对象的属性

  3. 参数命名的意义

    • 使用 _x 是为了避免与属性名 x 冲突

    • 也可以使用 this.x = x 的写法

  4. 实际效果

    new Point(3.0, 4.0); 
    // 创建的对象:{ x:3.0, y:4.0 }

这样设计的Point类,能确保每个点对象创建时都有明确的坐标位置。

问题三:

上面代码中的p1.中的“.”有什么作用

在 Java 中,p1.getDistance(origin) 里的点号(.)是一个非常重要的操作符,它的作用可以概括为:

点号(.)的三大核心作用

  1. 访问对象的成员

    • 就像「的」字在中文里的作用

    • p1.getDistance 表示「p1 的 getDistance 方法」

    • p1.x 表示「p1 的 x 属性」

  2. 连接对象和它的属性/方法

    • 左侧是对象(p1

    • 右侧是该对象的成员(getDistance方法)

  3. 触发方法调用

    • 当后面跟的是方法时(如 getDistance()),表示要执行这个方法

在代码中的具体解析

Point p1 = new Point(3.0, 4.0);
Point origin = new Point(0.0, 0.0);
System.out.println(p1.getDistance(origin));
  1. p1 是一个 Point 类的对象(实例)

  2. getDistancePoint 类中定义的方法

  3. . 表示:「请调用 p1 这个点的 getDistance 方法」


类比现实世界理解

假设你有一部手机(对象):

  • 手机.开机() → 调用手机的开机功能

  • 手机.电量 → 查看手机的电池属性

你的 Point 类就像设计图,p1 是按这个设计图造出来的具体产品,. 就是操作这个产品的「按钮」


与其他语法的对比

表达式

作用

类比

p1.x

访问 p1 的 x 属性

「查看手机的屏幕尺寸」

p1.getDistance()

调用 p1 的 getDistance 方法

「使用手机的拍照功能」

Point.count

访问 Point 类的静态成员

「查看手机品牌的所有产量」


特别注意事项

  1. null 对象不能用 .

    Point p2 = null;
    p2.getDistance(origin); // 抛出 NullPointerException
  2. private 成员外部不能访问

    System.out.println(p1.x); // 如果 x 是 private 的,这里会报错
  3. 链式调用(多个 . 连续使用)

    String s = "Hello";
    int length = s.toUpperCase().substring(1).length();

内存中的实际运作

栈内存       堆内存
p1   →    Point对象 {
             x: 3.0
             y: 4.0
             getDistance(): {...}
          }

origin → Point对象 {
             x: 0.0
             y: 0.0
          }

当执行 p1.getDistance(origin) 时:

  1. Java 根据 p1 的引用找到堆中的 Point 对象

  2. 找到该对象的 getDistance 方法

  3. origin 作为参数传入执行


为什么需要点号?

没有点号的话,代码将无法表达:

  • 哪个对象执行操作

  • 具体操作是什么

就像如果没有「的」字:

  • 「我书包」可能表示「我的书包」或「我是一个书包」

文章作者:Eila

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!