java.lang.Object 类是Java语⾔中的根类,即所有类的⽗类。
Object类当中包含的⽅法有11个:
1.需要重写 toString(),equals(),hashCe();
2.线程有关wait(),notify(), notifyAll();
3.其他 getClass(),finalize(),clone();
如果⼀个类没有特别指定⽗类,那么默认则继承⾃Object类。例如:
public class MyClass /extends Object/ { // … }
⽅法摘要
public String toSting():返回该对象的字符串表示
toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值
覆盖重写
如果不希望使⽤toString⽅法的默认⾏为,则可以对它进⾏覆盖重写。例如⾃定义的Person类:
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
// 省略构造器与Getter Setter
}
在IntelliJ IDEA中,可以点击 Code 菜单中的 Generate… ,也可以使⽤快捷键 alt+insert ,点
击 toString() 选项。选择需要包含的成员变量并确定。如下图所示
native方法,用于返回对象的哈希吗,主要使用在哈希表中,比如jdk中的 HashMap
⽅法摘要
public boolean equals(Object obj) :指示其他某个对象是否与此对象“相等”。
调⽤成员⽅法equals并指定参数为另⼀个对象,则可以判断这两个对象是否是相同的。这⾥的“相 同”有默认和⾃定义两种⽅式。
1.默认地址⽐较
如果没有重写equals方法,那么Object类中默认进行**==**运算符 的对象地址比较,只要不是同一个对象,结果必然是false.
2.对象内容⽐较
如果希望进行对象的内容比较,即所有或指定的部分成员变量相同就判定两个对象相同,则可覆盖重写equals方法。例如:
import java.util.Objects;
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object o) {
// 如果对象地址⼀样,则认为相同
if (this == o)
return true;
// 如果参数为空,或者类型信息不⼀样,则认为不同
if (o == null || getClass() != o.getClass())
return false;
// 转换为当前类型
Person person = (Person) o;
// 要求基本类型相等,并且将引⽤类型交给java.util.Objects类的equals静态⽅
法取⽤结果
return age == person.age && Objects.equals(name, person.name);
}
}
在IntelliJ IDEA中,可以使⽤ Code 菜单中的 Generate… 选项,也可
以使⽤快捷键 alt+insert ,并选择 equals() and hashCode() 进⾏⾃动代码⽣成。如下图所
示
在⽐较两个对象的时候,Object的equals⽅法容易抛出空指针异常,⽽Objects类中的equals⽅
法就优化了这个问题。⽅法如下:
public static boolean equals(Object a, Object b) :判断两个对象是否相等
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
public final Class> getClass()
返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
Java的引用变量有两个类型,编译时类型和运行时类型。
1.编译时类型由声明该变量时使用的类型决定。(=左边)
2.运行时类型由实际赋给该变量的对象决定。(=右边)
object.作用:对象通过该方法,可以获得对应的类的字节码对象
xx.java ->xx.class ->JVM
类加载-方法区-字节码对象
加载:类只加载一次,所以方法区中类型信息只有一个,对应的字节码对象都是同一个。
加载触发的条件:
1.实例化对象 new
2.静态方法/静态变量
3.使用子类,父类必须先加载
4.class.forName(“java.lang.Sting”)–手动加载指定的类
5.Strin.class->获得字节码对象
举例
定义student类:
public class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
主方法实现
public class Demo {
public static void main(String[] args) throws Throwable {
System.out.println("------Class getClass()----");
Student stu1 = new Student("qw", 12);
Student stu2 = new Student("ae", 12);
Class aClass = stu1.getClass();
Class aClass1 = stu2.getClass();
//同种类型的对象,对应的字节码对象都是同一个
System.out.println(aClass==aClass1);//true
深克隆:复制对象 是复制一份全新的,属性内容一致的对象,但内存中的地址值一定不一样
浅克隆:复制引用
定义Clone类
public class Clone {
String name;
int age;
public Clone(String name, int age) {
this.name = name;
this.age = age;
}
public Clone() {
}
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 class ZiClone extends Clone implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
主方法实现
public class Demo {
public static void main(String[] args) throws Throwable {
ZiClone zi = new ZiClone();
/*深克隆复制是对象 */
zi.setName("lucy");
Object clone= zi.clone();//多态
ZiClone clone1=(ZiClone)clone;
//==对比是时地址值
System.out.println(zi==clone1);//false
//复制出来的在堆中的内存位置不一样
/*浅克隆 复制引用*/
ZiClone clone2=zi;
System.out.println(zi==clone2);//true
}
}
内存溢出:在内存中没有存储的地方
内存泄漏:内存被无效对象占用
一个对象分配内存之后,在使用是没有来得释放,导致一直在占用内存,使得实际内存变少
GC 垃圾回收机制,定时清理内存
1.在程序运行时自动启动,不定时回收内存中标记的垃圾(没有引用的对象,会被内存标记为垃圾)
2.GC是自动调用的,也可以手动调用GC -System.gc();
总结:原则上java中是不存在内存泄漏的
native 方法,并且不能重写。
作用是:暂停线程的执行。
注意:sleep() 方法没有释放锁,wait释放了锁。timeout 是等待时间。
比上者多了 nanos参数,表示额外的时间(以毫秒为单位,范围是 0 - 999999)
跟上面两个一样,只不过该方法会一直等下去,没有超时这个概念
native方法,并且不能重写。
唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)
如果有多个线程在等待只会唤醒一个。
native方法,并且不能重写。
作用跟 notify() 一样,只不过会唤醒在此对象监视器上等待的所有线程,而不是一个线程。