Java 6——成员变量初始值 object equals和== toString instanceof 参数传递问题

成员变量初始值

Java中所有的变量必须先声明,后赋值才能使用

Java中的成员变量,在创建对象的时候,都会执行一次初始化操作,都会给一个默认值

基本数据类型默认值都是0,包括boolean -> false

引用数据类型:null

null表示空,什么都没有,占位

object

所有的东西都是对象

在Java中所有的类都要继承object

object是一个类,是所有类的根

我们写的类即使不写继承关系,那么默认也会继承object

equals和==

==判断左右两端的数据是或否一致

equals:object类提供的一个方法,用来判断两个对象是否相等

equals可以自己重写

字符串的判断一定要用equals来判断

== :运算符,用于比较两个变量的值是否相等

对于基本数据类型(int, double, char, boolean 等):比较的是数值本身

对于引用数据类型(类、接口、数组等):比较的是内存地址(即是否指向同一个对象)

equals() :方法,属于 java.lang.Object 类,用于比较两个对象的内容是否相等 。默认实现(Object 类中的 equals)与 == 相同,也是比较地址。但许多类(如 StringIntegerDate 等)重写了 equals 方法,使其比较实际内容

一句话总结:== 比较"是不是同一个";equals 比较"内容是否相同"(在重写后)

java 复制代码
int a = 10;
int b = 10;
System.out.println(a == b);   // true

char c1 = 'A';
char c2 = 'A';
System.out.println(c1 == c2); // true

对于基本类型,== 直接比较数值

java 复制代码
class Person {
    String name;
    Person(String name) { this.name = name; }
}

Person p1 = new Person("张三");
Person p2 = new Person("张三");
Person p3 = p1;

System.out.println(p1 == p2);      // false(不同对象,地址不同)
System.out.println(p1.equals(p2)); // false(Object 默认比较地址)
System.out.println(p1 == p3);      // true(同一个对象)

对于自定义类,如果没有重写 equals,则 ==equals 效果相同:都比较地址

java 复制代码
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");

// == 比较地址
System.out.println(s1 == s2);   // true(字符串常量池,指向同一对象)
System.out.println(s1 == s3);   // false(s3 在堆中新建对象)
System.out.println(s3 == s4);   // false(两个不同对象)

// equals 比较内容
System.out.println(s1.equals(s2)); // true
System.out.println(s1.equals(s3)); // true
System.out.println(s3.equals(s4)); // true

String 类重写了 equals,比较字符序列内容。但需注意字符串常量池的影响

equals== 的比较表格
类型 == 比较什么 equals 比较什么(默认) equals 重写后比较什么
基本数据类型 数值 不可用 -
引用类型(未重写 equals) 内存地址(是否同一对象) 内存地址(同 == -
String 地址(注意常量池) 字符串内容 内容
包装类(Integer 等) 地址(但有缓存范围) 数值 数值
数组 地址 地址(未重写) 一般用 Arrays.equals()
自定义类(重写 equals 地址 可自定义为逻辑相等 自定义内容

toString

默认的toString() -> 包+类@内存地址

toString() 对一个对象的字符串的表示形式

Java官方推荐你重写这个方法

instanceof

instanceof:判断xxx对象是否是xxx类型

参数传递问题

值传递:把变量的值作为参数进行传递

引用传递:直接把变量作为参数进行传递

Java使用的是值传递

一句话:参数传递的是"值",只不过这个值对于引用类型来说是对象的地址

java 复制代码
public class Test {
    public static void change(int x) {
        x = 100;   // 修改的是局部副本
        System.out.println("方法内部: x = " + x);
    }

    public static void main(String[] args) {
        int a = 10;
        change(a);
        System.out.println("方法外部: a = " + a);
    }
}
// 输出:
// 方法内部: x = 100
// 方法外部: a = 10

当参数是基本类型时,方法接收的是原始值的拷贝。方法内部对参数的任何修改都不会影响外部变量

内存分析

java 复制代码
栈内存:
main: a = 10
change: x = 10 (拷贝,修改 x 不影响 a)

当参数是引用类型时,传递的是引用的拷贝 (即对象地址的副本)。方法内部可以通过这个地址访问和修改对象的内容,但无法改变原始引用变量指向的对象

java 复制代码
class Person {
    String name;
    Person(String name) { this.name = name; }
}

public class Test {
    public static void changeName(Person p) {
        p.name = "李四";   // 通过引用修改对象内容(有效)
    }

    public static void changeRef(Person p) {
        p = new Person("王五");   // 修改的是引用的副本(无效)
        System.out.println("方法内部: p.name = " + p.name);
    }

    public static void main(String[] args) {
        Person person = new Person("张三");
        changeName(person);
        System.out.println(person.name);   // 李四

        changeRef(person);
        System.out.println(person.name);   // 李四(未被改变)
    }
}
// 输出:
// 李四
// 方法内部: p.name = 王五
// 李四

内存分析

java 复制代码
栈内存:
main: person -----> 堆内存对象 { name = "张三" }
changeName: p -----> 同一对象(地址拷贝)
    p.name = "李四";   // 修改对象内容,原始 person 也看到变化

changeRef: p -----> 同一对象(地址拷贝)
    p = new Person("王五");   // p 指向新对象,但原始 person 仍指向原对象
常见误区澄清
误区 正确理解
"Java 对引用类型是引用传递" 错误。Java 只有值传递,传递的是引用的值(地址)。
"方法内修改参数会影响外部变量" 对于基本类型,不会;对于引用类型,只能修改对象内容,不能改变引用本身。
"交换两个对象参数可以影响外部" 不能,因为交换的是引用的副本。
"字符串传递时修改会生效" 不会,因为字符串是不可变的,任何改变都会产生新对象。
"数组参数传递的是数组本身" 传递的是数组引用的副本,但可以通过索引修改元素。
相关推荐
中新传媒1 小时前
德宸堂心理双师同诊
java·前端·数据库
想唱rap1 小时前
NAT、内网穿透、代理服务
java·linux·网络·网络协议·udp·智能路由器
故事和你911 小时前
洛谷-【图论2-1】树6
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
被AI抢饭碗的人1 小时前
C++过渡Python
开发语言·python
不知名的老吴1 小时前
在C++中不用宏怎么打日志的使用建议
开发语言·c++·算法
环流_1 小时前
nacos环境隔离
java·服务器·前端
芋只因1 小时前
天机学堂学习笔记
java·笔记·学习
jieyucx1 小时前
Go 语言进阶:结构体指针、new 关键字与匿名结构体/成员详解
开发语言·后端·golang·结构体
摇滚侠1 小时前
Spring 面试题 真正的 offer 偏方 Java 基础 Java 高级
java·后端·spring