toString()
在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串);
可以通过重写toString()方法表示出对象的属性。
此方法是在打印对象时被调用的,下面有两个范例,一个是没复写toString()方法,另一个是复写了toString()方法,读者可比较两者的区别。
public class TestToStringDemo1 {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p);
}
}
class Person extends Object {
String name = "张三";
int age = 18;
}
输出结果:
educoder.Person@7852e922
从上面的程序中可以发现,在打印对象p的时候实际上打印出的是一些无序的字符串,这样的字符串很少有人能看懂什么意思,之后可以再观察下面的范例,下面的范例复写了Object类中的toString()方法。
public class TestToStringDemo2 {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p);
}
}
class Person extends Object {
String name = "张三";
int age = 18;
// 复写Object类中的toString()方法
public String toString() {
return "我是:" + this.name + ",今年:" + this.age + "岁";
}
}
输出结果:
我是:张三,今年:18岁
与 TestToStringDemo1.java程序相比,程序TestToStringDemo2.java 在 Person
类中明确复写了 toString()方法,这样在打印对象p的时候,实际上是去调用了toString()方法,只是并没有明显的指明调用 toString()方法而已,此时第 6 行相当于:
System.out.println(p.toString());
equals()
比较的是对象的引用是否指向同一块内存地址,一般情况下,比较两个对象时是比较它的值是否一致,那如何解决呢?思路也比较简单,重写equals()方法。
在不重写的情况下,我们先看下程序执行情况,创建两个相同类型的对象,并判断对象是否相等。
public class test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "jack";
Dog dog1 = new Dog();
dog1.name = "jack";
System.out.println(dog);
System.out.println(dog1);
if (dog.equals(dog1)) {
System.out.println("两个对象是相同的");
} else {
System.out.println("两个对象是不相同的");
}
}
}
class Animal {
}
class Dog extends Animal {
int age = 20;
String name = "rose";
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
}
输出结果:
Dog [age=20, name=jack]
Dog [age=20, name=jack]
两个对象是不相同的
分析下 : 两个对象分别new了一次,开辟了两个不同内存空间,内存地址不同。object提供的equals()是用来比较的是对象的引用是否指向同一块内存地址。很显然,内存地址不一样,所以是不相等的,跟属性值是否一样完全没有任何关系。
一般情况下,我们是需要判断对象的属性值相等的,那么如何重写 equals()方法呢?通过Eclipse(集成开发环境)提供的快捷键,Dog类中出现如下方法,方法的解释也放在代码中一并进行解释如下:
public class test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "jack";
Dog dog1 = new Dog();
dog1.name = "jack";
System.out.println(dog);
System.out.println(dog1);
if (dog.equals(dog1)) {
System.out.println("两个对象是相同的");
} else {
System.out.println("两个对象是不相同的");
}
}
}
class Animal {
}
class Dog extends Animal {
int age = 20;
String name = "rose";
public String toString() {
return "Dog [age=" + age + ", name=" + name + "]";
}
/* getClass() 得到的是一个类对象 */
@Override
public boolean equals(Object obj) {
if (this == obj)// 两个对象的引用是否相同,如果相同,说明两个对象就是同一个
return true;
if (obj == null)// 如果比较对象为空,不需要比较,肯定不相等
return false;
if (getClass() != obj.getClass())// 比较两个对象的类型是否相同,如果不同,肯定不相同
return false;
Dog other = (Dog) obj;// 转化成相同类型后,判断属性值是否相同
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
输出结果:
Dog [age=20, name=jack]
Dog [age=20, name=jack]
两个对象是相同的
equals() 和== 的区别:
在Java中,任何类型的数据都可以用 “==”进行比较是不是相等,一般用于基本数据类型的比较,比较器存储的值是否相等。但是如果用于引用类型(类,接口,数组)的比较,则是比较所指向对象的地址是否相等,在这点上,跟object类提供的equals()方法的作用是一致的。
对于equals()方法
- 首先,不能用于基本数据类型的变量之间的比较相等;
- 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
- 诸如String、Date等类都对equals方法进行了重写,比较的是所指向的对象的内容。
clone()方法
对象克隆是一种创建对象的精确副本的方法。Object类的clone()方法用于克隆对象。new关键字创建对象的引用,而clone()方法能实现克隆一个新的副本。java.lang.Cloneable接口必须由我们要创建其对象克隆的类实现。如果我们不实现Cloneable接口,clone()方法将生成CloneNotSupportedException。
clone()方法在Object类中定义。 clone()方法的语法如下:
protected Object clone() throws CloneNotSupportedException
clone()方法保存用于创建对象的精确副本的额外处理任务。 如果我们使用new关键字执行它,它将需要执行大量的处理,这就是为什么我们使用对象克隆。
public class Student implements Cloneable {
int rollno;
String name;
Student(int rollno, String name) {
this.rollno = rollno;
this.name = name;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String args[]) {
try {
Student s1 = new Student(101, "amit");
Student s2 = (Student) s1.clone();
System.out.println(s1.rollno + " " + s1.name);
System.out.println(s2.rollno + " " + s2.name);
} catch (CloneNotSupportedException c) {
}
}
}
输出结果:
101 amit
101 amit