在比较字符型数据时,==比较的是内存中的地址,比较的是对象的句柄;而equals()比较的是地址内的内容,比较的是对象。由于JAVA中除基本数据类型外其它一切都是对象,而对象变量存储的都是引用,相当于C中的指针,所以在比较对象时如String,用==是比较两个变量是否指向同一个对象,而用equals才是比较两个String的内容是否相等。
      ==绝对比equals快。
      ==是java内置的,可以理解为"相同"。对于简单类型来说,a=3,b=3,我们可以说a和b相同,也可以说a和b相等,都没什么问题。.equals()是Object的方法,可以理解为"相等"。显然两个object相等并不意味着相同;但是需要注意的是,也并不意味着他们对应内存区域的所有字节都相等,比如(但不限于这个原因)他们内部可能还有自己的引用。所以,两个对象是否相等,只有这个对象自己才知道如何判断,java并不知道。所以就需要类自己提供一个equals方法。下面举例说明:

题目:
  Integer     new   Integer(42)  
  Long     new   Long(42)  
  Double     new   Double(42.0)  
  下面哪些返回true  
  1:   i==l  
  2:   i==d  
  3:   l==d  
  4:   i.equals(l)  
  5:   i.equals(d)  
  6:   l.equals(d)  
  7:   i.equals(42)  
答案:7;

编码验证:
public   class   Equivalence     
   public   static   void   main(String[]   args)   
      Integer     new   Integer(42)  
      Long     new   Long(42)  
      Double     new   Double(42.0)  
      System.out.println(i==l);  
      System.out.println(i==d);
      System.out.println(l==d);  
      System.out.println(i.equals(l) );   
      System.out.println(i.equals(d) );
      System.out.println(l.equals(d) );  
      System.out.println(i.equals(42));
  


运行结果:
1-3:编译不通过;
4-6:false
7:true

原理解释:
1.   检查对象是否相等
关系运算符==和!=也适用于所有对象,但它们的含义通常会使初涉Java领域的人找不到北。下面是一个例子:
//:   Equivalence.java  
public   class   Equivalence   
   public   static   void   main(String[]   args)   
      Integer   n1    new   Integer(47);  
      Integer   n2    new   Integer(47);  
      System.out.println(n1   ==   n2);  
      System.out.println(n1   !=   n2);  
   }  
  ///:~
      其中,表达式System.out.println(n1 == n2)可打印出内部的布尔比较结果。一般人都会认为输出结果肯定先是true,再是false,因为两个Integer对象都是相同的。但尽管对象的内容相同,句柄却是不同的,而==和!=比较的正好就是对象句柄。所以输出结果实际上先是false,再是true。这自然会使第一次接触的人感到惊奇。
      若想对比两个对象的实际内容是否相同,又该如何操作呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“主类型”,那些类型直接使用==和!=即可。下面举例说明如何使用:
//:   EqualsMethod.java 
public   class   EqualsMethod   
   public   static   void   main(String[]   args)   
      Integer   n1    new   Integer(47);  
      Integer   n2    new   Integer(47);  
      System.out.println(n1.equals(n2));  
   }  
  ///:~  
正如我们预计的那样,此时得到的结果是true。但事情并未到此结束!假设您创建了自己的类,就象下面这样:
//:   EqualsMethod2.java 
class   Value   
   int   i;  
}
public   class   EqualsMethod2   
   public   static   void   main(String[]   args)   
      Value   v1    new   Value();  
      Value   v2    new   Value();  
      v1.i    v2.i    100;  
      System.out.println(v1.equals(v2));  
   }  
  ///:~  
此时的结果又变回了false!这是由于equals()的默认行为是比较句柄。所以除非在自己的新类中改变了equals(),否则不可能表现出我们希望的行为。但要注意equals()的这种行为方式同时或许能够避免一些“灾难”性的事件。     
      大多数Java类库都实现了equals(),所以它实际比较的是对象的内容,而非它们的句柄。
      在java中内存分为“栈”和“堆”(Stack   and   Heap) ,基本数据类型存储在"栈"中,对象引用类型实际存储在"堆"中,在“栈”中只是保留引用内存的地址值,就好像知道你家门牌号码就可以找到你家。在Java中利用"=="比较变量时候,系统使用变量在stack(栈)中所存的值来作为对比的依据,基本数据类型(int   float   double   boolean)在stack中所存的值就是其內容值,而引用类型在stack中所存放的值是本身所指向Heap中对象的地址值,而不是原先所設定的值。

PS  
1:
      ==基本类型之间的比较包括int,short,reference等  
      equals()是对象之间的比较,缺省(Object中)的是对象引用的比较,但是可以重载。  
2:
      equals()和==在语义上是不同的,==是作为标识符嵌入到java语言的语法中,
      而equals()是作为一个类方法实现。java的指称语义,必须描述==,但是不用描述equals()方法。