Object类
Object类是所有类的父类(基类)。如果一个类没有明确的继承某一个具体的类,则将默认继承Object类。
例如定义一个类:
public class Person {
}
其实它在被使用时,是这样的:
public class Person extends Object{
}
Java中所出现的所有东西都可看成是Object类的对象。
Object类的多态
使用Object可以接收任意的引用数据类型。
案例:
public class Demo {
public static void main(String[] args) {
String text = "锄禾日当午";
say(text); //打印 锄禾日当午
int a = 10;
say(a); //打印 10
double d = 6.66;
say(d); //打印 6.66
}
public static void say(Object o){
System.out.println(o);
}
}
控制台输出:
锄禾日当午
10
6.66
由以上代码,可得知Object接收任意的数据类型
Object类的方法
变量和类型 | 方法 | 描述 |
---|---|---|
protected Object | clone() | 创建并返回此对象的副本。 |
boolean | equals(Object obj) | 指示某个其他对象是否“等于”此对象。 |
protected void | finalize() | **(已过时)**最终确定机制本质上存在问题。 |
类<?> | getClass() | 返回此Object的运行时类。 |
int | hashCode() | 返回对象的哈希码值。 |
void | notify() | 唤醒正在此对象监视器上等待的单个线程。 |
void | notifyAll() | 唤醒等待此对象监视器的所有线程。 |
String | toString() | 返回对象的字符串表示形式。 |
void | wait() | 导致当前线程等待它被唤醒,通常是 通知或 中断 。 |
void | wait(long timeoutMillis) | 导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。 |
void | wait(long timeoutMillis, int nanos) | 导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。 |
toString方法
toString方法是Object类里的一种方法。
格式:
public String toString() {
// 返回对象的字符串表示形式
return "字符串内容";
}
通常,toString方法返回一个“文本表示”此对象的字符串。在编写代码时,代码的运行结果应该是简洁的信息丰富的表示,便于人们阅读。建议所有子类都覆盖此方法。
Object类的toString方法返回一个字符串,该字符串由对象为实例的类的名称,符号字符“@”以及对象的哈希码的无符号十六进制表示形式组成。简而言之,toString方法返回一个等于值的字符串:
getclass().getName() + '@' + Integer.toHexString(hashCode())
案例:
public class Person {
// 定义两个私有变量
private String name;
private int age;
// 调用get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 创建全参的构造方法
public Person (String name,int age) {
super();
this.name = name;
this.age = age;
}
// 创建无参的构造方法
public Person() {
super();
}
}
public class Demo {
// 程序的入口
public static void main(String[] args) {
Person p = new Person("张三",18);
System .out.println(p);
}
}
查询源码的快捷键:Ctrl + 鼠标左键。
查询println方法的源码:
public void println(Object x) {
String s = String.valueOf(x);
synchronized(this) {
print(s);
newLine();
}
}
再查询valueOf方法的源码:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString
}
通过查询源码,我们可以看出println打印出来的是toString表示形式的值,其中代码System .out.println(p);
相等于System .out.println(p.toString);
,只是toString方法被隐藏而已。
由于每一个类都继承了Object类,则每一个类都有从Object类中继承了toString方法
。所以在编写代码时,需要输出更详细的信息,则需要重写toString方法
。
重写toString方法
创建的快捷键:
Alt + Shift + S → Generate toString,点击进入选择需要描述的对象即可。
**重写的原则:**通过文字更仔细的描述对象的信息。上述程序代码中,需要重写toString方法
的话,只需在Person类的java
文档里添加toString方法
即可。
修改后的完整代码为:
Person.java文档内的代码:
public class Person {
// 定义两个私有变量
private String name;
private int age;
// 调用get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 创建全参的构造方法
public Person (String name,int age) {
super();
this.name = name;
this.age = age;
}
// 创建无参的构造方法
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Demo.java文档内的代码:
public class Demo {
// 程序的入口
public static void main(String[] args) {
Person p = new Person("张三",18);
System .out.println(p);
}
}
控制台打印出的内容:
Person [name=张三, age=18]
equals方法
public boolean equals(Object obj)
常见的 ==
等于号表示的是将等号两边的内存地址进行比较是否相等。而equals方法
则表示某个其他对象是否**“等于”**此对象。
Object类内的equals方法
:实现了对象上最具区别的可能等价关系; 也就是说,对于任何非空引用值x和y ,当且仅当x和y引用同一对象( x == y具有值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 ,多次调用x.equals(y)始终返回true或始终返回false ,前提是未修改对象
上的equals比较中使用的信息。 - **非空性 **:对于任何非空的参考值x , x.equals(null)应该返回false 。
类Object
的equals
方法实现了对象上最具区别的可能等价关系; 也就是说,对于任何非空引用值x
和y
,当且仅当x
和y
引用同一对象( x == y
具有值true
)时,此方法返回true
。
请注意,通常需要在重写此方法时覆盖hashCode
方法,以便维护hashCode
方法的常规协定,该方法声明相等对象必须具有相等的哈希代码。
案例:
Person.java文档内的代码:
public class Person {
// 定义两个私有变量
private String name;
private int age;
// 调用get、set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 创建全参的构造方法
public Person (String name,int age) {
super();
this.name = name;
this.age = age;
}
// 创建无参的构造方法
public Person() {
super();
}
// toString方法
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
// equals方法
public boolean equals(Object obj) {
if(this == obj) {
// 判断当前对象与obj对象的内存地址是否相同,如果相同则返回true
return true;
}
if(obj == null) {
// 判断obj对象是否为空(null),如果为空则返回false
return false;
}
if(obj instanceof Person) {
// 判断obj对象的类型是否和当前对象的类型相同(即同为Person类型)
Person p2 = (Person)obj;// 类型相同,将obj对象强转为Person类
if(this.name.equals(p2.name) && this.age ==p2.age) {
// 相同
return true;
}
}
return false;
}
}
Demo.java文档内的代码:
public class Demo {
// 程序的入口
public static void main(String[] args) {
Person p1 = new Person("张三",18);
Person p2 = new Person("张三",18);
System .out.println(p1.equals(p2));
}
}
控制台打印的内容
true
上述代码中的功能,判断p1和p2的name、age是否相同,相同返回true,不相同返回false。
equals方法
可以使用快捷键来生成,操作:Alt + Shift + S → Generate equals(),点击进入选择需要描述的对象即可。代码为:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}