/*
- Object类
- 1,Object类是所有Java类的根父类,如果在类的声明中未使用extends关键字指明其父类,则默认父类 为java.lang.Object类
- 也就是说所有类的对象都可以使用Object类定义的方法,Object类只提供一个空参构造器。
- 2,Object类中的方法:常用 equals()比较,toString()输出,clone()复制对象,hashCode()集合使用
- getClass()查询对象所属的类,finalize()垃圾回收器GC回收对象前调用此方法,notify(),notifyAll(),wait(),多线程使用
- 3,== 和equals()的区别
- 3.1是运算符, 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型
- 就是比较内存地址。
- 3.2equals()属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也
- 是==;我们可以看到String等类的equals()方法是被重写过的,而且String类在日常开发中
- 用的比较多,久而久之,形成了equals()是比较值的错误观点。
- 3.3具体要看自定义类里有没有重写Object的equals方法来判断。通常情况下,重写equals()方法,会比较类中的相应属性是否都相等。
- 4 ==运算符如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等,(类型不一定相同)
- 如果比较引用数据类型变量,比较的是两个变量的地址值是否相同。即两个引用 是否指向堆空间中的同一个对象实体。
- 特别的注意String s1 = new String(“A”);和s1 = “A”;的区别,两种方式使用==比较后的结果不同,
- 因为字符串数据类型储存在常量池中,不在堆空间。常量池中的数据如果两个对象都赋值为同一数据,那么堆空间中的变量都会指向
- 常量池中的同一地址。
- equals()是方法而非运算符,方法只适用于引用数据类型。
- 在Object类中定义的equals()方法和==作用相同,比较的是对象的地址值
- 在String,Date,File,包装类(Wrapper Class)中都重写了Object中的equals()方法,比较的不再是地址值
- 而是比较两个对象实际值是否相同。
- 自定义类中可以重写equals()方法,用于比较两个对象的属性值是否都相同。
- 5,自定义类重写equals()方法的原则
- 5.1,对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
- 5.2,自反性:x.equals(x)必须返回是“true”。
- 5.3,传递性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
- 5.4,一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
- 5.5,任何情况下,x.equals(null),永远返回是“false”; x.equals(和x不同类型的对象)永远返回是“false”。
- eclips中提供了自动重写hashCode()与equals()的功能。
- 5.6.如果类A中的属性有引用数据类型类B,那么在重写类A的 equals()方法后,也需要重写类B的equals()方法.
- 6,toString()方法;
- 6.1 toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
- 6.2在进行String与其它类型数据的连接操作时,自动调用toString()方法
- 例如MyDate a = new MyDate();
- System.out.println(a);等同于 System.out.println(a.toString());输出地址值
- 6.3可以根据需要在用户自定义类型中重写toString()方法,如String 类重写了toString()方法,返回字符串的值。
- 例如String s = “Hello”; System.out.println(s);等同于 System.out.println(s.toString());输出Hello
- 其余还有Date,File,包装类(Wrapper class)都重写了toString()方法。在调用时不返回地址值而是实际信息
- 6.4基本类型数据转换为String类型时,调用了对应包装类的toString()方法
- 例如int a = 11; System.out.println(a);
- 7.Eclips中单元测试(JUnit)的使用
- 步骤1,选中当前工程–右键选择build path --add Library --JUnit
- 步骤2,创建一个java类进行测试,
- 测试类的要求:类的权限为public,提供一个公共的无参构造器
- 步骤3,在类中创建一个单元测试方法
- 测试方法要求:方法的权限为public,无返回值,无形参
- 步骤4,此方法上需要声明一个@Test,并在测试类中导入import java.org.junit.Test
- 步骤5,声明好单元测试方法以后,可以在方法体内测试相关的代码
- 步骤6,写完测试代码后,左键双击单元测试方法名,右键:run as – JUnit Test
- 说明:
- 1,如果执行结果没有异常,显示绿条
- 2,如果执行结果有异常,显示红条和错误信息
- 3,简易方法,找到或创建测试类后,输入@Test,然后输入public void 方法名(){}
- 后使用ctrl + 1自动修复来完成导包和导入JUnit的操作。
*/
package object_chapter2;
import java.lang.Object;
public class Object_Class {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.getClass());//class object_chapter2.Person
System.out.println(p.getClass().getSuperclass());//class java.lang.Object
int[] arr = new int[10];
int[] arr1 = arr.clone();
arr1 = null;//将对象赋值为null,暗示gc可以回收对象
System.gc();//通知gc回收对象
Runtime.getRuntime().gc();//通知gc回收对象
//垃圾回收机制不可预知,无法精确执行垃圾回收,垃圾回收只针对JVM堆内存的对象空间
//垃圾回收机制对于其他物理连接比如数据库连接,IO流,Socket连接无能为力。
//如果覆盖finalize方法,将一个新的引用变量重新引用该对象,则会重新激活对象
//不要主动调用对象的finalize方法,应由垃圾回收器执行。
//测试==运算符
int i = 10;
int j = 10;
double d = 10.0;
char c = 10;
System.out.println(i == j);//true
System.out.println(i == d);//true ,对于运算符都有自动类型提升
char c1 = 'a';
int k = 97;
System.out.println(i == c);//true
System.out.println(k == c1);//true,对于char型数据 ==比较的是ASCII值。
//boolean类型无法与其他基本数据类型比较。
p = new Man();
Man m = (Man) p;
System.out.println(p == m);//true
String s1 = new String("A");//创建String类型的对象
String s2 = new String("A");
System.out.println(s1 == s2);//false,比较对象地址值,不相同
s1 = "A" ;//为String类型的对象赋值
s2 = "A" ;
System.out.println(s1 == s2);//true,字符串数据储存在常量池中,同一数据的地址值相同。
//测试equals()方法
System.out.println("----------------------------");
Person p1 = new Person("Fun",23);
Person p2 = new Person("Fun",23);
System.out.println(p1.equals(p2));//false,执行Object类中的方法,与==作用相同,比较地址值
System.out.println(s1.equals(s2));//true,执行String类中重写的方法,比较实际值,
Moon moon = new Moon();
MyDate m1 = new MyDate(1,1,1999,moon);
MyDate m2 = new MyDate(1,1,2000,moon);
m2.setYear(1999);
System.out.println(m1.equals(m2));
m2 = null;
System.out.println(m1.equals(m2));
//toString()方法测试
Moon moon1 = new Moon();
System.out.println(moon1);
System.out.println(moon1.toString());
String k1 = "Key";
System.out.println(k1);
System.out.println(k1.toString());
System.out.println(m1.toString());
}
}
class MyDate{
private int day;
private int month;
private int year;
private String str = "公历";
private Moon moon;
public MyDate() {
super();
}
public MyDate(int day, int month, int year, Moon moon) {
super();
this.day = day;
this.month = month;
this.year = year;
this.moon = moon;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public Moon getMoon() {
return moon;
}
public void setMoon(Moon moon) {
this.moon = moon;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(obj instanceof MyDate) {
MyDate m = (MyDate)obj;
return this.day == m.day && this.month == m.month &&
this.year == m.year && this.str.equals(m.str) &&
this.moon.equals(m.moon);
//this.str.equals(m.str)不能改写为this.str == m.str。
//如果形参使用m.setStr(new String("非闰年"))的方式传入参数,地址值就会不同,使用 == 比较会返回false。
//如果形参使用m.setStr("非闰年")的方式传入,因为数据储存在常量池中,所以相同数据只有一个地址值,使用 == 比较会返回true
}else {
return false;
}
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString() + "\n" + getClass() + "[" + year + "年" + month + "月" + day + "日," + str + "]";
}
}
class Moon{
private int cycle = 28;
@Override
public boolean equals(Object obj) {//eclips自动重写的equals()方法
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Moon other = (Moon) obj;
if (cycle != other.cycle)
return false;
return true;
}
}