java.lang是提供利用 Java 编程语言进行程序设计的####基础类。

我们可以将该包大致分成以下几类

Object

Class

数字与字符(包装器)类

线程与进程类

Math类

Runtime类

System类

我们首先讲讲很重要的object类。有一句话是这样的

在java里,一切皆对象。

所以Object类在java里占有举足轻重的重要性。

主要方法

首先我们看看Object类有哪些方法:

private void registerNatives()
Class< > getClass()
int hashCode()
boolean equals(Object obj)
protected Object clone()
String toString()
void notify()
void notifyAll()
void wait(long timeout)
void wait(long timeout, int nanos)
void wait()
protected void finalize()
1. private void registerNatives()

对象初始化的时候会自动调用 这个方法。是在c(c++)中实现的本地方法,其主要作用是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。

2. Class< > getClass()

返回的是此Object对象的类对象/运行时类

3.int hashCode()

在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。

如果两个对象相等(equal),那么必须拥有相同的哈希码(hash code)

即使两个对象有相同的哈希值(hash code),他们不一定相等.

根据上面可以看出:

一般重写equals方法的时候hashcode方法也要被重写的,因为相等的对象的hashcode一定相等

4.boolean equals(Object obj)
public boolean equals(Object obj) {
return (this == obj);
}

我们可以看到其实就是对两个对象的内存地址的比较。

ps:有些包装类String 、Math、Integer等重写了equals()方法,就是对内容的比较了。

5 protected Object clone()

这里涉及到深拷贝和浅拷贝的问题:

简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误

我们可以看到clone方法是protect 直接调用是不可以的,但是protect在子类是可以调用的,在java所有的类都缺省继承了Object类。所以我们只需要关心重写的clone这个方法。重写的方法需要继承

public interface Cloneable {
}
然后在对象里重写clone()方法
public Object clone(){
Object o=null;
try {
o=super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
重写了clone方法的当前类的复制是深拷贝,但是如果再该类里面存在另一个对象没有重写clone方法就是浅拷贝。实例如下
public class ObjectUseDto implements Cloneable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private ShallowCopy shallowCopy;
public ShallowCopy getShallowCopy() {
return shallowCopy;
}
public void setShallowCopy(ShallowCopy shallowCopy) {
this.shallowCopy = shallowCopy;
}
public Object clone() {
Object o = null;
try {
//Object中的clone()识别出你要复制的是哪一个对象。
o = super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e.toString());
}
return o;
}
}
class ShallowCopy {
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
调用方代码
ObjectUseDto test=new ObjectUseDto();
test.setName("小花");
ShallowCopy shallowCopy=new ShallowCopy();
shallowCopy.setAge(11);
test.setShallowCopy(shallowCopy);
ObjectUseDto test2=(ObjectUseDto)test.clone();
System.out.println(test2.getName());
System.out.println(test2.getShallowCopy().getAge());
test.setName("大猫");
shallowCopy.setAge(88);
System.out.println(test2.getName());
System.out.println(test2.getShallowCopy().getAge());

输出的结果

小花

11

小花

88

可以看出重写了clone的是深拷贝,每次我们改变的都是原有对象。原有的对象发生了改变从‘小花’变成‘大猫’了 但是拷贝的对象并没有发生改变,再看原有的age从 11 变成了 88 。

6 String toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

没有被重写的时候 表示没有被覆盖的时候,返回类名@哈希值,哈希值是十六进制的

7 protected void finalize()

我们先说下finalize()方法

可以看做一个析构方法 会在没有引用的时候再垃圾回收之前被垃圾回收机制调用

后面的方法主要是与多线程相关的了。

8 void notify() 只能在同步控制方法或者同步控制块里面使用

这个方法的主要功能是 唤醒在此对象监视器上等待的单个线程

9 void notifyAll() 只能在同步控制方法或者同步控制块里面使用

这个方法的主要功能是 唤醒在此对象监视器上等待的所有线程

10 void wait() 只能在同步控制方法或者同步控制块里面使用

这个方法的主要功能是 调用此方法所在的当前线程等待,直到在其他

线程上调用此方法的主调(某一对象)的notify()/notifyAll()方法。

在这里我们可以比较下sleep()的区别:

在调用sleep()方法的过程中,线程不会释放对象锁。

而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

11 void wait(long timeout) 只能在同步控制方法或者同步控制块里面使用

这个方法的主要功能是 线程等待 直到在其他线程上调用此方法的主调(某一对象)的notisfy()/notisfyAll()方法 或者等到一定时间

12 void wait(long timeout, int nanos) 只能在同步控制方法或者同步控制块里面使用

这个方法的主要功能是 线程等待 直到在其他线程上调用此方法的主调(某一对象)的notisfy()/notisfyAll()方法 或者等到一定时间

native 关键字

我们可以看到在Object类里有很多的方法都声明了native关键字那么native关键字有什么作用呢?

说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问

final关键字

一旦声明这个类,方法,变量为final ,那么这个引用将不能被改变,当再次尝试初始化会编译错误

finalize() 方法:

可以看做一个析构方法 会在没有引用的时候再垃圾回收之前被垃圾回收机制调用