equals和==的區別 (Java基礎)


1. == 是一個運算符。
2.Equals則是string對象的方法,可以.(點)出來。
  
  我們比較無非就是這兩種 1、基本數據類型比較 2、引用對象比較
  1、基本數據類型比較
  ==和Equals都比較兩個值是否相等。相等為true 否則為false;
  
  2、引用對象比較
  ==和Equals都是比較棧內存中的地址是否相等 。相等為true 否則為false;
  
  需注意幾點:
  1、string是一個特殊的引用類型。對於兩個字符串的比較,不管是 == 和 Equals 這兩者比較的都是字符串是否相同;
  2、當你創建兩個string對象時,內存中的地址是不相同的,你可以賦相同的值。
  所以字符串的內容相同。引用地址不一定相同,(相同內容的對象地址不一定相同),但反過來卻是肯定的;
  3、基本數據類型比較(string 除外) == 和 Equals 兩者都是比較值;

在談論equals和==的區別前,我們先簡單介紹一下JVM中內存分配的問題。

JVM中 內存分為棧內存和堆內存。二者有什么區別呢?

當我們創建一個對象(new Object)時,就會調用它的構造函數來開辟空間,將對象數據存儲到堆內存中,與此同時在棧內存中生成對應的引用,當我們在后續代碼中調用的時候用的都是棧內存中的引用,還需注意的一點,基本數據類型是存儲在棧內存中。有了一定的了解 我們來看Equals和==的區別。

 

 

首先equals和== 最大的區別是一個是方法一個是運算符,在Java中,二者比較的都是物理地址 而不是值得比較。

我們舉個例子這樣比較直觀。

Student student1 = new Student();

Student student2 = new Student();

System.out.println(student1.equals(student2));

System.out.println(student1 == student2);

不論是用的是哪一種方法 最終的結果顯示的都是false,大家不妨可以試一下。為什么呢?就是因為他們比較的不是對象中字段的值或者說本身對象的值,而比較的是物理地址。

我們再來舉一個例子。

String a = new String("a");

String b = new String("a");

System.out.println(a == b);

System.out.println(a.equals(b));

當我們創建2個String對象是 我們會發現 執行的結果是 false true。為什么這次euqals返回的值編程了true?因為此時equals方法不單單是比較物理地址 同時也比較了值,

String中 equals方法被重寫 當物理地址不同時,會進一步比較值,代碼如下:

if(object instanceof String){}

那么問題來了 當我調用

System.out.println(student1.toString().equals(student2.toString()));時,結果又是怎樣的?

結果卻返回了false.為什么呢?這就牽扯到了hashcode的問題。

那么為了保證兩個對象比較值相等有什么辦法么?想必大家都試過重寫equals方法,而最終的結果都不如人意。為什么?因為單單重寫equals方法並不能改變hashcode值,在java中 首先比較的就是hashcode。那么如何結果這個問題?

大家可以嘗試 右鍵->source->generate hashcode() and equals() 來實現。

 

 

 

public class EqualTest { 
public static void main(String[] args) { 

    //對於基本類型的變量。"==""equal"的區別 
    int t1=57; 
    int t2=67; 
    int t3=124; 
    int t4=124; 
     
    //“==”對於基本數據類型,判斷兩個變量的值是否相等。 
    Boolean result1=(t1==t2); 
    Boolean result2=((t1+t2)==t3); 
    Boolean result3=(t3==t4); 
     
    System.out.println("/n/n-----t1==t2"+result1+"/n-----(t1+t2)=t3"+result2+"/n-----t3=t4"+result3); 
    //“equal”不能用於基本數據類型。只能用於類變量。對於基本數據類型要用其包裝類。 
    Integer i1=new Integer(t1); 
    Integer i2=new Integer(t2); 
    Integer i3=new Integer(t3); 
    Integer i4=new Integer(t4); 
     
     
    Boolean ri1=i1.equals(i2); 
    Boolean ri2=i3.equals(i1+i2); 
    Boolean ri3=i3.equals(i4); 
     
    System.out.println("/n/n-----i1.equals(i2)"+ri1+"/n-----i3.equals(i1+i2)"+ri2+"/n-----i3.equals(i4)"+ri3); 
   
    //對於對象變量,"==""equal"的區別 

    String st1="wasiker "; 
    String st2="is super man"; 
    String st3="wasiker is super man"; 
    String st4="wasiker is super man"; 
     
    Boolean b1=(st1==st2); 
    Boolean b2=(st1+st2)==st3; 
    Boolean b3=(st3==st4); 
     
    System.out.println("/n/n-----st1==st2"+b1+"/n-----(st1+st2)==st3"+b2+"/n-----st3==st4"+b3); 

//因為對象變量的存儲的是對象在內存中的路徑,即內存地址。所以用“==”比較時,即使 
//對象的值相等,但是他們的內存地址不同,所以==的結果為false。故“==”用於比較兩 
//個變量的值是否相等,而不是變量引用的對象是否相等 

    Boolean r1=st1.equals(st2); 
    Boolean r2=(st1+st2).equals(st3); 
    Boolean r3=st3.equals(st4); 
     
    System.out.println("/n/n-----st1.equals(st2)"+r1+"/n-----(st1+st2).equals(st3)"+r2+"/n-----st3.equals(st4)"+r3); 

//equal用於比較兩個對象是否相同。 
} 

運行結果為: 
-----t1==t2false 
-----(t1+t2)=t3true 
-----t3=t4true 

-----i1.equals(i2)false 
-----i3.equals(i1+i2)true 
-----i3.equals(i4)true 

-----st1==st2false 
-----(st1+st2)==st3false 
-----st3==st4true 

-----st1.equals(st2)false 
-----(st1+st2).equals(st3)true 
-----st3.equals(st4)true 

總之: 
“==”比較的是值【變量()內存中存放的對象的()內存地址 
equal用於比較兩個對象的值是否相同【不是比地址】 

【特別注意】Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等等一些類,是重寫了equals方法,才使得equals“==不同,所以,當自己創建類時,自動繼承了Objectequals方法,要想實現不同的等於比較,必須重寫equals方法。

"==""equal"運行速度快,因為"=="只是比較引用.

在談論equals和==的區別前,我們先簡單介紹一下JVM中內存分配的問題。

JVM中 內存分為棧內存和堆內存。二者有什么區別呢?

當我們創建一個對象(new Object)時,就會調用它的構造函數來開辟空間,將對象數據存儲到堆內存中,與此同時在棧內存中生成對應的引用,當我們在后續代碼中調用的時候用的都是棧內存中的引用,還需注意的一點,基本數據類型是存儲在棧內存中。有了一定的了解 我們來看Equals和==的區別。

 

 

首先equals和== 最大的區別是一個是方法一個是運算符,在Java中,二者比較的都是物理地址 而不是值得比較。

我們舉個例子這樣比較直觀。

Student student1 = new Student();

Student student2 = new Student();

System.out.println(student1.equals(student2));

System.out.println(student1 == student2);

不論是用的是哪一種方法 最終的結果顯示的都是false,大家不妨可以試一下。為什么呢?就是因為他們比較的不是對象中字段的值或者說本身對象的值,而比較的是物理地址。

我們再來舉一個例子。

String a = new String("a");

String b = new String("a");

System.out.println(a == b);

System.out.println(a.equals(b));

當我們創建2個String對象是 我們會發現 執行的結果是 false true。為什么這次euqals返回的值編程了true?因為此時equals方法不單單是比較物理地址 同時也比較了值,

String中 equals方法被重寫 當物理地址不同時,會進一步比較值,代碼如下:

if(object instanceof String){}

那么問題來了 當我調用

System.out.println(student1.toString().equals(student2.toString()));時,結果又是怎樣的?

結果卻返回了false.為什么呢?這就牽扯到了hashcode的問題。

那么為了保證兩個對象比較值相等有什么辦法么?想必大家都試過重寫equals方法,而最終的結果都不如人意。為什么?因為單單重寫equals方法並不能改變hashcode值,在java中 首先比較的就是hashcode。那么如何結果這個問題?

大家可以嘗試 右鍵->source->generate hashcode() and equals() 來實現。

 

 

 

public class EqualTest { 
public static void main(String[] args) { 

    //對於基本類型的變量。"==""equal"的區別 
    int t1=57; 
    int t2=67; 
    int t3=124; 
    int t4=124; 
     
    //“==”對於基本數據類型,判斷兩個變量的值是否相等。 
    Boolean result1=(t1==t2); 
    Boolean result2=((t1+t2)==t3); 
    Boolean result3=(t3==t4); 
     
    System.out.println("/n/n-----t1==t2"+result1+"/n-----(t1+t2)=t3"+result2+"/n-----t3=t4"+result3); 
    //“equal”不能用於基本數據類型。只能用於類變量。對於基本數據類型要用其包裝類。 
    Integer i1=new Integer(t1); 
    Integer i2=new Integer(t2); 
    Integer i3=new Integer(t3); 
    Integer i4=new Integer(t4); 
     
     
    Boolean ri1=i1.equals(i2); 
    Boolean ri2=i3.equals(i1+i2); 
    Boolean ri3=i3.equals(i4); 
     
    System.out.println("/n/n-----i1.equals(i2)"+ri1+"/n-----i3.equals(i1+i2)"+ri2+"/n-----i3.equals(i4)"+ri3); 
   
    //對於對象變量,"==""equal"的區別 

    String st1="wasiker "; 
    String st2="is super man"; 
    String st3="wasiker is super man"; 
    String st4="wasiker is super man"; 
     
    Boolean b1=(st1==st2); 
    Boolean b2=(st1+st2)==st3; 
    Boolean b3=(st3==st4); 
     
    System.out.println("/n/n-----st1==st2"+b1+"/n-----(st1+st2)==st3"+b2+"/n-----st3==st4"+b3); 

//因為對象變量的存儲的是對象在內存中的路徑,即內存地址。所以用“==”比較時,即使 
//對象的值相等,但是他們的內存地址不同,所以==的結果為false。故“==”用於比較兩 
//個變量的值是否相等,而不是變量引用的對象是否相等 

    Boolean r1=st1.equals(st2); 
    Boolean r2=(st1+st2).equals(st3); 
    Boolean r3=st3.equals(st4); 
     
    System.out.println("/n/n-----st1.equals(st2)"+r1+"/n-----(st1+st2).equals(st3)"+r2+"/n-----st3.equals(st4)"+r3); 

//equal用於比較兩個對象是否相同。 
} 

運行結果為: 
-----t1==t2false 
-----(t1+t2)=t3true 
-----t3=t4true 

-----i1.equals(i2)false 
-----i3.equals(i1+i2)true 
-----i3.equals(i4)true 

-----st1==st2false 
-----(st1+st2)==st3false 
-----st3==st4true 

-----st1.equals(st2)false 
-----(st1+st2).equals(st3)true 
-----st3.equals(st4)true 

總之: 
“==”比較的是值【變量()內存中存放的對象的()內存地址 
equal用於比較兩個對象的值是否相同【不是比地址】 

【特別注意】Object類中的equals方法和“==”是一樣的,沒有區別,而String類,Integer類等等一些類,是重寫了equals方法,才使得equals“==不同,所以,當自己創建類時,自動繼承了Objectequals方法,要想實現不同的等於比較,必須重寫equals方法。

"==""equal"運行速度快,因為"=="只是比較引用.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

服務器層3

1. entity類  實體類3

2. DAO4

*(2)Mapper映射器的要求:4

3. service層  (開始寫注解掃描@6

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

服務器層

1.  entity類  實體類

1.  數據庫復制字段

/*

 * 類屬性名和屬性數據類型

 * 與數據庫cn_user字段名及數據類型

 * 保持一致

 */

 

 

String 類型     后面為分號

2.  get set 方法  tostring(可以控制台輸出)

 

 

2.  DAO     

1. interface UserDao 接口    mapper映射

public User findByName(String name);

其中User  調用 entity層的user實體類

 

 

2.  Mapper映射器

*(2)Mapper映射器的要求:

a.  接口方法的名稱與映射文件中的sql的id要一樣。
b. 方法的參數類型要與映射文件當中的parameterType 一致。
c. 方法的返回類型要與映射文件當中的resultType一致。
此外,映射文件的namespace必須等於Mapper映射器的 全限定名。

 

<?xml version="1.0" encoding="UTF-8" ?>  

<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      

 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

 

 <mapper namespace="cn.tedu.cloud_note.dao.UserDao">

         <select parameterType="string" resultType="cn.tedu.cloud_note.entity.User">

                select * from cn_user where cn_user_name={#name};

         </select>

 

 

 

 

 </mapper>

 

 

 

 

單元測試dao

@Test   //1.要寫 test

 

public void TestUserDao(){  

 

    ApplicationContext ctx=new ClassPathXmlApplicationContext("conf/spring-myBatis.xml");

// 2.applicationContest   掃描   config配置文件

        UserDao dao=ctx.getBean("userDao",UserDao.class);

//3.getBean   UserDao.class   要大寫

User user=dao.findByName("demo");

//4.調用DAO層 檢測數據庫

System.out.println(user);

 

3.  service層  (開始寫注解掃描@)

1.附加的  cn.tedu.cloud_note.util

1.1創建類    實體類 NoteResult<T>  注意<T>

private int status;

private String msg;

private T data;

cn.tedu.cloud_note.util

 

public class NoteResult<T> implements Serializable

狀態   123數字表示

消息

數據

Get  set  tostring方法

 

 

  

1.2創建NoteUtil

1.2.1UUID生成主鍵

1.2.2MD5加密處理

 

package cn.tedu.cloud_note.util;

 

import java.security.MessageDigest;

import java.util.UUID;

import org.apache.commons.codec.binary.Base64;

 

public class NoteUtil {

    //利用UUID生成主鍵

//UUID(Universally Unique Identifier)全局唯一標識符,

//是指在一台機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的。

public static String create(){

UUID uuid=UUID.randomUUID();

String id=uuid.toString();

return id.replace("-", "");

}

//md5加密

public static String md5(String src){

try {

MessageDigest md=MessageDigest.getInstance("MD5");

//MD5加密處理

byte[] output

=md.digest(src.getBytes());

//Base64處理

String ret=Base64.encodeBase64String(output);

return ret;

} catch (Exception e) {

throw new NoteException("密碼加密失敗",e);

}

 

}

}

 

1.3  創建 NoteException     來拋異常

    package cn.tedu.cloud_note.util;

 

public class NoteException extends  RuntimeException {

//注意是RuntimeException   不是 Exception  (出現報錯 直接點開創建會開始這個

//spring事務管理時,

//只有遇到RuntimeException時才回滾

public NoteException(String msg,Throwable t){

super(msg,t);

}

}

2. 

2.1接口 interface 

public interface UserService {

       public NoteResult<User> checkLogin(String name ,String password);

                         

}

傳入參數   String name   String password

2.2UserService  

public class UserServiceImpl

implements UserService

2.2.1  

@Service("userService") //掃描的Spring容器

 

2.2.2 獲取資源Resource

@Resource

private UserDao userDao;

 

2.2.3   方法里面寫

  //接收結果數據

NoteResult<User> result=new NoteResult<User>();

2.2.4    處理業務   排除用戶名和密碼都錯誤的狀態   

       //按參數name查詢數據庫

User user=userDao.findByName(name);

 

  //檢測用戶名

if(user==null){    //報錯  name==null  改成 user

result.setStatus(1);

result.setMsg("用戶名不存在");

return result;

}

//檢測密碼

String md5Password=NoteUtil.md5(password);

if (!user.getCn_user_password().equals(md5Password)) {

result.setStatus(2);

result.setMsg("密碼錯誤");

return result;

}

//用戶名和密碼都正確

result.setStatus(0);

result.setMsg("登錄成功");

result.setData(user);

return result;

}

 

 

Service單元測試

 

package test.service;

 

import org.junit.Before;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.tedu.cloud_note.entity.User;

import cn.tedu.cloud_note.service.UserService;

import cn.tedu.cloud_note.util.NoteResult;

 

public class TestUserService {

UserService service;

@Before

public void init(){

String[] conf={"conf/spring-mybatis.xml",

       "conf/spring-mvc.xml",

       };

ApplicationContext ctx

=new ClassPathXmlApplicationContext(

conf);

service

=ctx.getBean("userService",UserService.class);

}

 //NoteResult <User>  調用noteresult實體類  entity.User實體類

@Test  //用例-1:預期結果:用戶名不存在

public void test1(){

NoteResult<User> result

=service.checkLogin("你好", "123");

System.out.println(

service.getClass().getName());

System.out.println(result);

//System.out.println(result.getStatus());

//System.out.println(result.getMsg());

//System.out.println(result.getData());

}

}

 

 

 

4.  controller層

Controller層是service層和頁面的對接

1.調用 service  資源  resource

2.頁面上 匹配請求  requestmapping(請求地址)

寫方法 調用service層然后return

NoteResult result

=userService.checkLogin(name, password);

 

 

類里面要調用,方法里面也要調用

方法用的與service是一樣的

 

@Controller

public class UserLoginController {

@Resource

UserService service;

 

@RequestMapping("/user/login.do")  //頁面請求

@ResponseBody//調用json

public NoteResult<User> execute(String name,String password){

System.out.println(name+"+"+password);

NoteResult<User> result=service.checkLogin(name, password);//調用service

return result;

 

}

 

 

 

controller測試

 http://localhost:8080/cloud_note3/user/login.do

 

出現 {"status":1,"msg":"用戶名不存在","data":null}

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM