目录
打印对象和toString方法
【toString()方法】
负责把返回把该对象的“描述性字符串”打印输出成一个对象时,实际上打印的是该对象的toString()方法的返回值。可以说就是toString()方法的重写(@override)
Object类提供飞toString()方法返回值就是:类名@hashcode值 —— 很多时候,程序员需要去重写toString()方法
【toString方法的标准重写】
public String toString(){
return "toStringTest[name=" + name + ",weight" + weight + "]";
} //先写类名,依次罗列出所有属性名和属性值
class Apple {
private String name;
private String color;
private double weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public Apple() {
}
public Apple(String name, String color, double weight) {
this.name = name;
this.color = color;
this.weight = weight;
}
public String toString() {
return "toStringTest[name = " + name + ", color = " + color + ", weight = " + weight + "]";
}
}
public class ToStringTest {
public static void main(String[] args) {
Apple a = new Apple("apple", "red", 5.56);
System.out.println(a);
}
}
运行结果
==和equals()方法
【boolean equals(Object obj)方法】
这个方法用于“按自己的规则判断两个是否相等”,==用于判断两个基本类型的变量(表达式/直接式),他们的值是否相等。
public class EqualsTest {
public static void main(String[] args) {
int it=65;
float f1=65.0f;
//将输出true
System.out.println("65和65.0f是否相等:"+(it==f1));
char ch='A';
//将输出true
System.out.println("65和‘A’是否相等:"+(it==ch));
String str1=new String("hello");
String str2=new String("hello");
//将输出false,因为==如果不是同一个对象之间,就是false
System.out.println("str1和str2是否相等:"+(str1==str2));
//将输出true,这里就是equals方法在String中的方法特性,就是只要字符串相同就输出false
System.out.println("str1和str2是否相等:"+str1.equals(str2));
}
}
- ==中,基本类型只比较实际值,不管它的数据类型
- 如果是引用的变量(不包括包装类,因为包装类可以自动拆箱),==要求被比较的两个引用变量用同一个实例才能返回true
- equals在String中,String重写了equals()方法,只要两个字符串包含的字符串相同,就返回true
- 在创建构造器是需要建立一个空构造器
【==在字符串中的问题】
- JVM常量池保证相同的字符串直接量只有一个(缓存)——即一个“好好学习,天天向上”,不会产生多个副本,这类字符串在编译器的时候就确定下来,这是,他们将引用同一个字符串对象,与new一个新的对象,两个对象的相同字符串是不同的。
- 而间接拼接时,指向的对象就不是同一个了,仅仅只是内容上相同而已。因为系统会先创建一个对象内容是“好好学习,”,然后再创建一个对象“天天向上”。
public class StringCompareTest {
public static void main(String[] args) {
//s1会被缓存
String s1 = "好好学习,天天向上";
String s2 = "好好学习,";
String s3 = "天天向上";
String s4 = "好好学习" + "," + "天天向上";
//s2是变量、s3也是变量,所以他们的值只有在运行时才会确认
//所以s5的值也会动态确认,都不会缓存
String s5 = s2 + s3;
//编译时,JVM中+号相当于没有,+前后都是“直接量”
System.out.println(s1 == s4);
System.out.println(s1 == s5);
System.out.println(s1);
System.out.println(s4);
System.out.println(s5);
//System.identityHashCode(Object); 方法可以返回对象的内存地址
//以下的代码可以看出s1和s4是同一个对象,s5和前两者不是同一个对象。尽管3者输出一样
System.out.println(System.identityHashCode(s1));
System.out.println(System.identityHashCode(s4));
System.out.println(System.identityHashCode(s5));
}
}
输出结果
【equals方法重写的模板】
public boolean equals(Object obj){
//如果this(自己),obj(被比较的一个实例)
//本身这两个就是同一个东西
if(this == obj){
return true;
}
//obj.getClass()用于获取obj所引用对象的类型
if(obj.getClass() == Dog.class){
//被比较类型非空同时比较关键的特征/主键
if(obj != null && ……){
return true;
}
}
}
class Person {
private String name;
private String idStr;
// 创建一个无参数的构造器
public Person() {
}
// 创建有参数的构造器
public Person(String name, String idStr) {
this.name = name;
this.idStr = idStr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdStr() {
return idStr;
}
public void setIdStr(String idStr) {
this.idStr = idStr;
}
@Override
public boolean equals(Object obj) {
// 如果this(自己),obj(被比较的一个实例)
// 本身这两个就是同一个东西
if (this == obj) {
return true;
}
// obj.getClass()用于获取obj所引用对象的类型
if (obj != null && obj.getClass() == Person.class) {
// 被比较类型非空同时比较关键的特征/主键
Person personObj = (Person)obj;
// 并且当前对象的idStr和obj对象的idStr相等时才能判断两个对象是否一致
if (this.getIdStr().equals(personObj.getIdStr())) {
return true;
}
}
return false;
}
}
public class OverrideEqualsRight {
public static void main(String[] args) {
Person p1 = new Person("小张", "123456");
Person p2 = new Person("小李", "123456");
Person p3 = new Person("小张", "151256");
System.out.println("小张和小李是否为同一个人:" + p1.equals(p2)); //将输出true
System.out.println("小张和小张是否为同一个人:" + p1.equals(p3)); //将输出false
}
}
【写equals的标准】
- 若当前对象与被比较对象本身相同,直接返回true
- 若当前对象与被比较对象的类型相同,关键属性值也相同 —— 此时才返回true
【写equals的标准(离散数学版)】
- 自反性:对任意x,x.equals(x)一定返回true
- 对称性:对任意的x和y,若x.equals(y)返回值为true,那么y.equals(x)返回值也为true
- 传递性:对任意的x,y和z,若x.equals(y)返回值为true且y.equals(z)返回值也为true,那么x.equals(z)返回值也为true
- 一致性:对任意的x和y,若对象中用于等价比较的信息没有改变,无论调用多少次equals方法,返回值也是一致的
- 对任何不是null的x,x.equals(null)一定返回false