面试:Object 方法与原理

作者: Tim在路上 | 来源:发表于2020-05-23 14:13 被阅读0次

    Object 方法与原理

    1. clone 方法

    clone 方法的用法是对象的浅拷贝和深拷贝,clone是浅拷贝是对基本类型的值传递,对引用类型进行引用类型般的拷贝。深拷贝并拷贝对象的所有属性,并拷贝属性所指向的动态分配内存。实现深拷贝的方法有:1. 重写clone方法,对其内部的引用类型再进行clone. 2.通过序列化实现深拷贝,将拷贝的对象写入内存的字节流中,然后在读出转换为对象。新对象和原对象不存在地址的共享,所以实现深拷贝。3. 可以采用反射来实现深拷贝,迭代的依次拿到字段,并给新对象赋值。

    拓展:java序列化的问题?

    java 序列化是对对象的压缩便于存储和传输,但是为什么序列化不是默认添加,而是需要实现一个标志接口。

    最大的问题是对象的引用问题,例如现在有A,B两个类。
    此时空间上分配两个空间来存储 A,B对象。

    如果B类中含有一个指向A类对象的引用,因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,内存分配了三个空间,而对象a同时在内存中存在两份。必须对a进行修改等操作,需要维护每一份的拷贝来达到数据的一致性。不是默认序列化很重要的一个原因就是为了安全,java的类安全机制是做的很好的.

    序列化的漏洞,如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

    序列化ID的作用?

    序列化ID起着关键的作用,java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。反序列化时,JVM会把传来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。

    2. getClass 方法

    getClass, .class, getName 的区别:

    getClass 只能使用在实例类,是运行时获得类型,.class 在编译时获得一个类的对象,getName 是获得对象的名称

    class.forName() jvm 查找并加载指定类,如果类中有静态初始化器,执行代码段。

    newInstance() 创建对象,必须保证1.类已经加载,2.类已经连接。java1.9中,newInstance已经弃用,使用class.getDeclaredConstructor().newInstance();

    3. equals 方法

    “==” 比较两个对象是否是同一个对象,比较的两个对象的地址(基本数据是值,引用是地址)

    没有覆盖equals和“==”一样,我们常见的对象类型,都是已经重写equals比较的是对象的内容

    当然Integer 对象,有个静态的类IntegerCache,当缓存数值为-128 ~ 127 下限是固定的,127上限可以调节,当定义两个数值在其中之间,“== ” 比较是 true, 否则“==” 比较是false

    4. hashcode 方法
    1. 如果 equals 方法判断两个对象相等,hashcode 也一定相等,hashcode 相等,equals 并不一定会相等,先用hashcode判断, 可以加快判断的速度。
    2. 重写 equals 一定要重写 hashcode
    4. wait() notify() notifyAll()

    wait() notify() notifyAll() 他们必须用在 同步代码块内, 调用wait()就是释放锁,释放锁的前提是必须要获得锁,先获得锁才能释放锁。

    wait() 是线程自动释放他们所占有的对象锁,并等待notify.

    notify(),唤醒一个正在wait当前对象锁的线程,并让其拿到对象。

    notifyAll() 唤醒所有正在wait当前对象锁的线程,接下来会竞争对象锁。平常使用过程中,还需要注意把wait()放到循环里面。如果采用if判断的话,wait线程唤醒会直接处理接下来的业务,但是可能出现另一种情况,条件语句已经不满足业务处理的条件了,所以需要再次进行判断。

    相关文章

      网友评论

        本文标题:面试:Object 方法与原理

        本文链接:https://www.haomeiwen.com/subject/knnkahtx.html