equals和==的区别 (Java基础)
Posted 南北12345678
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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==t2】false
-----【(t1+t2)=t3】true
-----【t3=t4】true
-----【i1.equals(i2)】false
-----【i3.equals(i1+i2)】true
-----【i3.equals(i4)】true
-----【st1==st2】false
-----【(st1+st2)==st3】false
-----【st3==st4】true
-----【st1.equals(st2)】false
-----【(st1+st2).equals(st3)】true
-----【st3.equals(st4)】true
总之:
“==”比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】
equal用于比较两个对象的值是否相同【不是比地址】
【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写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==t2】false
-----【(t1+t2)=t3】true
-----【t3=t4】true
-----【i1.equals(i2)】false
-----【i3.equals(i1+i2)】true
-----【i3.equals(i4)】true
-----【st1==st2】false
-----【(st1+st2)==st3】false
-----【st3==st4】true
-----【st1.equals(st2)】false
-----【(st1+st2).equals(st3)】true
-----【st3.equals(st4)】true
总之:
“==”比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】
equal用于比较两个对象的值是否相同【不是比地址】
【特别注意】Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。
"=="比"equal"运行速度快,因为"=="只是比较引用.
服务器层
1. 写entity类 实体类
1. 数据库复制字段
/*
* 与数据库cn_user字段名及数据类型
* 保持一致
*/
String 类型 后面为分号
2. get set 方法 tostring(可以控制台输出)
1. interface UserDao 接口 用mapper映射
public User findByName(String name);
其中User 调用 entity层的user实体类
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>
@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;
}
在http://localhost:8080/cloud_note3/user/login.do
出现 {"status":1,"msg":"用户名不存在","data":null}
以上是关于equals和==的区别 (Java基础)的主要内容,如果未能解决你的问题,请参考以下文章