面向对象(POP):将方法和数据封装为对象作为程序的基本单元,提炼出封装继承多态来作为代码指导,注重代码灵活性和复用性
面向过程(OOP):将过程作为基本程序的基本单元,过程对应到代码中就是函数,将函数和数据分离,注重步骤和流程
Person person = new Person()
你尝试打印 person 变量本身,输出可能是类似于"Person@12345678"的字符串
new Person()其实就是在堆中创建对象实体,而person就是对象的引用(放在栈内存中)
能,因为类有默认的无参构造方法,但一旦声明了有参构造,默认的无参构造方法就会消失,所以在添加了有参之后也要将无参构造声明出来
共同点:
区别:
深拷贝:完全拷贝一个对象,包括基本类型和引用类型
浅拷贝:只拷贝对象本身和基本类型,不拷贝引用类型
引用拷贝:两个不同的引用指向同一个对象
hashcode,equals(默认实现是==来判断),getclass,clone,toString,notify(唤醒线程),notifyall,wait,finalize(GC触发操作)
/**
* native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。
*/
public final native Class<?> getClass()
/**
* native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。
*/
public native int hashCode()
/**
* 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等。
*/
public boolean equals(Object obj)
/**
* native 方法,用于创建并返回当前对象的一份拷贝。
*/
protected native Object clone() throws CloneNotSupportedException
/**
* 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。
*/
public String toString()
/**
* native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
*/
public final native void notify()
/**
* native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。
*/
public final native void notifyAll()
/**
* native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。
*/
public final native void wait(long timeout) throws InterruptedException
/**
* 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。
*/
public final void wait(long timeout, int nanos) throws InterruptedException
/**
* 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
*/
public final void wait() throws InterruptedException
/**
* 实例被垃圾回收器回收的时候触发的操作
*/
protected void finalize() throws Throwable { }
==对于基本类型来说就是判断值是否相等,引用类型就是地址是否相等
equals不能判断基本数据类型,没有重写的equals就是==来实现的,重写了的就是看值是否相等(比如我想让一个对象的某个属性相等就认为这是一个对象就需要重写)
它的作用就是得到哈希码(int),确定该对象在哈希表中的位置,方便快速找到对象
hashcode的效率更高比equals
那为什么 JDK 还要同时提供这两个方法呢?
hashCode()
和 equals()
都是用于比较两个对象是否相等。因为hash算法会出现碰撞,不同的对象得到同一个hash值,而且当两者都返回true时我们才认为两个对象相等,这也是为什么重写equals时要重写hashcode的原因
String是不可变类,每次修改都会创建对象,导致资源浪费
StringBuider线程不安全
StringBuffer就是在StringBuider加上了sychronized同步锁线程安全但是牺牲了性能
但是StringBuider和StringBuffer两者底层使用的是char数组,如果在知道数据量的情况下,可以减少扩容,提高性能
String就是典型的不可变类,类用final修饰,变量用private final修饰且不对外暴露修改方法(setter等),fianl修饰导致不能被继承,避免子类修改
新版的 String 其实支持两个编码方案:Latin-1 和 UTF-16。如果字符串中包含的汉字没有超过 Latin-1 可表示范围内的字符,那就会使用 Latin-1 作为编码方案,而在这个方案下,byte占一个字节,char占两个字节,节省一半的内存空间,超过表示范围,两者占得空间一样
Java 语言本身并不支持运算符重载,“+”和“+=”是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的运算符。
使用+来创建对象实际是调用了StringBuilder的append方法实现的,然后调用tostring返回一个String对象,但是在循环下使用+会一直创建Stringbuilder对象,如果直接使用StringBuider就不会出现这种情况
为了避免重复创建字符串专门开辟的区域,提高jvm性能和减少内存消耗
一个或者两个,当字符串常量池不存在abc就会在堆上创建两个字符串对象,其中一个字符串对象引用就会保存在常量池中
String.intern()
是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:
String.intern()
是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况: