java中“==”与equals()的区别

发布时间 2023-12-06 11:09:12作者: 山茶花llia

"=="是运算符,equals()是方法

"=="

  1. 如果比较的是基本数据类型(int、short、long、char、float、double、boolean、byte),则比较的是值是否相等
  2. 如果比较的是引用数据类型,则比较的是对象的内存地址是否相等

equals()

比较对象的内容是否相同
    equals()方法存在于Object类中,而Object类是所有类的父类。在Object类中定义了equals方法:

    public boolean equals(Object obj) {
	return (this == obj);
    }
  1. 如果类未重写equals方法
       调用equals时,会调用Object中的equals方法(实际使用的也是==操作符)
  2. 如果类重写了equals方法
       调用equals时,会调用该类自己的equals方法(一般是比较对象的内容是否相同)。比如:
  •    String:比较字符串内容是否相同;
  •    Integer:比较对应的基本数据类型int的值是否相同。

值类型与引用类型

  在Java中类型可分为两大类:值类型与引用类型。值类型就是基本数据类型(如int ,double 等),而引用类型,是指除了基本的变量类型之外的所有类型(如通过 class 定义的类型)。

image

  所有的类型在内存中都会分配一定的存储空间(形参在使用的时候也会分配存储空间,方法调用完成之后,这块存储空间自动消失), 基本的变量类型只有一块存储空间(分配在stack中), 而引用类型有两块存储空间(一块在stack中,一块在heap中),在函数调用时Java是传值还是传引用,这个估计很多人至今都很糊涂,下面用图形与代码来解释:

image

  在上图中引用类型在传参时不是在heap中再分配一块内存来存变量c 所指向的A(),而是让a 指向同一个A 的实例,这就与C++ 中的指针一样,先声明指针变量a,b,c,d 在传参的时候让a 指向c所指向的内存,让 d 指向 b 所指向的内存。很明显Java中的引用与C++中的指针在原理上是相类似的,但记住Java没有指针,只有引用。下面再通过一些具体的代码来讨论引用:

  1. 简单类型是按值传递的

Java 方法的参数是简单类型的时候,是按值传递的 (pass by value)。这一点我们可以通过一个简单的例子来说明:

package test;
 
public class Test {
   //交换两个变量的值
  public static void Swap(int a,int b){
  int c=a;
      a=b;
      b=c;
      System.out.println("a: "+a);
      System.out.println("b: "+b);
   }
 
  public static void main(String[] args){
  int c=10;
  int d=20;
  Swap(c,d);
      System.out.println("After Swap:");
      System.out.println("c: "+d);
      System.out.println("d: "+c);
   }
}
运行结果:
a: 20
b: 10
After Swap:
c: 20
d: 10

  不难看出,虽然在 Swap (a,b) 方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响,即对 main(String[]) 方法里的 a,b 变量没有影响。那说明,参数类型是简单类型的时候,是按值传递的。以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法函数的,那么在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。

  1. 什么是引用

  Java 是传值还是传引用,问题主要出在对象的传递上,因为 Java 中简单类型没有引用。既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。

  简单的说,引用其实就像是一个对象的名字或者别名 (alias),一个对象在内存中会请求一块空间来保存数据,根据对象的大小,它可能需要占用的空间大小也不等。访问对象的时候,我们不会直接是访问对象在内存中的数据,而是通过引用去访问。引用也是一种数据类型,我们可以把它想象为类似 C++ 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。

如果我们定义了不止一个引用指向同一个对象,那么这些引用是不相同的,因为引用也是一种数据类型,需要一定的内存空间(stack,栈空间)来保存。但是它们的值是相同的,都指示同一个对象在内存(heap,堆空间)的中位置。比如:

String a="This is a Text!";

String b=a;

image

  通过上面的代码和图形示例不难看出,a 和 b 是不同的两个引用,我们使用了两个定义语句来定义它们。但它们的值是一样的,都指向同一个对象 "This is a Text!"。但要注意String 对象的值本身是不可更改的 (像 b = "World"; b = a; 这种情况不是改变了 "World" 这一对象的值,而是改变了它的引用 b 的值使之指向了另一个 String 对象 a)。
image

  如图,开始b 的值为绿线所指向的“Word Two”,然后 b=a; 使 b 指向了红线所指向的”Word“.