1、toString()方法
package com.company.objectMethods;
/*
* Object中的()方法
*
* SUN在Object类中设计方法的目的:返回java对象的字符串表示形式
*
* 在现实开发过程中,Object里面的方法已经不够用了。
* 因为Object的方法实现的结果不满意。
*
* Object中的方法就是要被重写的。
*
* print方法后面括号中如果是一个引用类型,会默认调用引用类型的方法。
*
* SUN是这样实现toString()方法的:
* public String toString() {
return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
}
* Object中的toString方法返回: 类名@java对象的内存地址经过哈希算法得出的int类型值再转换成十六进制
* 这个输出结果可以等同看做java对象在堆中的内存地址。
*
* */
public class ObjectToString {
public static void main(String[] args) {
// 创建一个Object对象
Object o1 = new Object();
// 调用()方法
String oStr = o1.toString();
System.out.println(oStr); // java.lang.Object@2d98a335
Person p1 = new Person("zhangsan",20);
String pStr = p1.toString();
System.out.println(pStr); // com.company.objectMethods.Person@7ef20235
// print方法后面括号中如果是一个引用类型,会默认调用引用类型的toString方法。
System.out.println(p1); // com.company.objectMethods.Person@7ef20235
/*
【注意】
System.out.println();里面如果是一个引用类型的话会默认输出 引用.toString();
但是查看System.out.println()源码:
public void println(Object x) {
String s = String.valueOf(x);
synchronized(this) {
this.print(s);
this.newLine();
}
}
public static String valueOf(Object obj) {
return obj == null ? "null" : obj.toString();
}
会发现:当引用为null的话,System.out.println() 会输出 null
当引用不是null的话,System.out.println() 会输出 引用.toString()
*/
People pe1 = new People("刘德华",45);
System.out.println(pe1.toString()); // People[name=刘德华,age= 45]@4f3f5b24
System.out.println(pe1); // People[name=刘德华,age= 45]@4f3f5b24
}
}
class Person{
String name;
int age;
public Person(){}
public Person(String name, int age){
this.name = name;
this.age = age;
}
}
class People{
String name;
int age;
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
// 重写toString方法。
// 根据项目的需求而定。例如要输出People[name=xxx,age=xxx]@16为哈希值
public String toString(){
return "People[name=" + name + ",age= " + age + "]" + "@" + Integer.toHexString(this.hashCode());
}
}
2、equals()方法
package com.company.objectMethods;
/*
* 关于Object中的equals方法:
*
* SUN公司源码:
* public boolean equals(Object obj) {
return this == obj;
}
* o1.equals(o2); o1是this, o2是obj
* == 两边如果是引用类型,则比较他们内存地址,地址相同则是true,反之则为false.
* Object中的equals方法比较的是两个引用的内存地址
*
*
* */
public class ObjectEquals {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
boolean b1 = o1.equals(o2);
System.out.println(b1); // false
Star s1 = new Star(100,"黄晓明");
Star s2 = new Star(100,"黄晓明");
Star s3 = new Star(110,"黄晓明");
// System.out.println(s1.equals(s2)); // false
// 由于业务逻辑需求,这个位置需要输出true
// 在现实业务逻辑中,不应该比较内存地址,应该比较内容。
// 所以Object中的equals方法需要重写。
System.out.println(s1.equals(s2)); //true
System.out.println(s1.equals(s3)); //false
}
}
class Star{
int id;
String name;
public Star(int id, String name){
this.id = id;
this.name = name;
}
// 根据需求规定:如果身份证号码一致,并且名字一致,则表示是同一个人
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj instanceof Star){
Star s = (Star)obj;
if(this.id == s.id && this.name == s.name){
return true;
}
}
return false;
}
}
关于String要小心的地方
package com.company.objectMethods;
/*【注意】
* 关于java语言中如何比较两个字符串是否一致?
* 在java中比较两个字符串是否一致,不能用"=="
* 只能调用String类中的equals方法
* */
public class TestString {
public static void main(String[] args) {
String s1 = new String("ABC");
String s2 = new String("ABC");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true 这个输出为true说明SUN公司在String类中重写了equals()方法
String s3 = "ABC";
String s4 = "ABC";
System.out.println(s3==s4); // true
System.out.println(s3.equals(s4)); // true
System.out.println(s3==s1); // false
System.out.println(s3.equals(s1)); // true
}
}
3、finalize()方法
package com.company.objectMethods;
/*
* 关于Object中finalize方法
* finalize方法与java垃圾回收机制有关联
*
* 垃圾回收机制(Garbage Collection),也叫GC,垃圾回收期主要有以下特点:
* ①当对象不再被程序使用时,垃圾回收器将会将其回收
* ②垃圾回收是在后台运行的,我们无法命令垃圾回收器马上回收资源,
* 但是我们可以告诉他,尽快回收资源(System.gc和Runtime.getRuntime().gc())
* ③垃圾回收器在回收某个对象的时候,首先会调用该对象的finalize方法
* ④GC主要针对堆内存
* ⑤单例模式的特点
*
* finalize()方法什么时候调用?
* 1、finalize方法每个java对象都有
* 2、finalize方法不需要程序员去调用,由系统自动调用。
* 3、java对象如果没有更多的引用指向它,则该java对象称为垃圾数据,等待垃圾回收器
* 的回收,垃圾回收器在回收这个java对象之前会自动调用该对象的finalize方法。
*
* finalize方法是该对象马上就要被回收了,例如:需要释放资源,则可以在该方法中释放。
* */
public class ObjectFinalize {
public static void main(String[] args) {
Person1 p1 = new Person1();
p1 = null; //没有引用再指向它,等待回收
// 程序员不能去干预垃圾回收器
// 程序员只能“建议”垃圾回收器回收垃圾
System.gc();
}
}
class Person1{
//重写Object中的finalize方法
// finalize在IDEA中会出现斜杠,提示:Overrides deprecated(不推荐的) method in java.lang.Object
public void finalize() throws Throwable{
System.out.println(this + "马上就要被回收了!"); // 这里的this会自动调用this.toString()方法
}
}
4、hashCode()方法
package com.company.objectMethods;
/*
* hashCode方法返回的是该对象的哈希码值
* java对象的内存地址经过哈希算法得出的int类型的数值
* */
public class ObjectHashCode {
public static void main(String[] args) {
ObjectHashCode o1 = new ObjectHashCode();
System.out.println(o1.hashCode()); //764977973
}
}
5、wait()、notify()、notifyAll() 方法
notify() :唤醒在此对象监视器上等待的单个线程。
notifyAll() : 唤醒在此对象监视器上等待的所有线程。
wait() : 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout) : 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
wait(long timeout, int nanos) : 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
为什么wait notify会放在Object里边?wait(),notify(),notifyAll()用来操作线程为什么定义在Object类中?
1、这些方法存在于同步中;
2、使用这些方法必须标识同步所属的锁;
3、锁可以是任意对象,所以任意对象调用方法一定定义在Object类中。
以下代码借鉴:https://blog.csdn.net/a460708485/article/details/82023662
代码中有几个坑,需要注意!!!
鉴于原文已经很详细了,这里去建议看原文。
public class WaitNotifyCase {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("thread A get lock");
TimeUnit.SECONDS.sleep(1);
System.out.println("thread A do wait method");
lock.wait();
System.out.println("wait end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lock");
synchronized (lock) {
System.out.println("thread B get lock");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notify();
System.out.println("thread B do notify method");
}
}
}).start();
}
}
结果:
thread A is waiting to get lock
thread A get lock
thread B is waiting to get lock
thread A do wait method
thread B get lock
thread B do notify method
wait end