常见基础问题
# equals和==区别?
首先明确一点, equals
是方法, ==
是操作符。
1. 如果比较的是基本数据类型:
只讨论 ==
,因为 equals
是不存在的,因为java中基本数据类型不能调用method的。
2. 如果比较的是引用类型:
==
:比较两个引用是不是指向同一个对象实例,即相同的地址。
equals
:equals
方法是 Object
类的方法,默认是直接调用 ==
来实现。如果没有被重写,那么调用 equals
与 ==
没有区别。但是,在一些类库中这个方法被覆盖了,比如八大基本数据类型的包装类和String类,它们的 equals
方法比较的是值是否相同,此时 equals
就与 ==
有区别了。
# java抽象类?
1.抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
2.由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。
3.在Java中抽象类表示的是继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
# 深拷贝和浅拷贝的区别?
拷贝针对的是引用对象的拷贝。
浅拷贝只复制指向某个对象的引用,不复制内存本身,新旧对象还是共享同一块内存。
深拷贝会复制一个一模一样的对象,新对象跟原对象不共享内存。
# java是值传递还是引用传递?
形式参数为基本数据类型的,就是值传递,如果为引用数据类型就是引用传递。
Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。
# 为什么重写equals还要重写hashcode?
如:重写一个自定义类的equals可以实现我们的意图,即这两个类判断为相等,但它们的hashcode是不同的。
如果我们用hashset去add的时候,由于底层是通过hashcode判断是不是同一对象,这个时候不重写hashcode就会被判断成不同对象。
# wait()等函数定义在Object中,而不是Thread中?
锁可以是任意对象,所以任意对象调用方法一定定义在Object类中。
# Java中的object九大方法?
protected Object clone() 创建并返回此对象的一个副本。
boolean equals(Object obj) 指示某个其他对象是否与此对象“相等”。
protected void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<? extendsObject> getClass() 返回一个对象的运行时类。
int hashCode() 返回该对象的哈希码值。
void notify() 唤醒在此对象监视器上等待的单个线程。
void notifyAll() 唤醒在此对象监视器上等待的所有线程。
String toString() 返回该对象的字符串表示。
void wait() 导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll() 方法。
void wait(long timeout) 导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或
void wait(long timeout, int nanos) 导致当前的线程等待,直到其他线程调用此对象的 notify()
# AOP比较?
1.AspectJ使用编译时和class文件加载时织入时,Spring AOP利用运行时织入。
2.Spring aop是基于代理的aop框架。这意味着, 要实现目标对象的各个方面, 它将创建该对象的代理。
使用以下两种方法之一实现:
1)JDK 动态代理 —— Spring AOP 的首选方式。只要目标对象实现甚至一个接口, 就会使用 JDK 动态代理;
2)CGLIB 代理 —— 如果目标对象没有实现接口, 则可以使用 CGLIB 代理。
3. AspectJ在实际运行之前就完成了织入,所以说它生成的类是没有额外运行时开销的。
# sleep()方法和wait()方法区别和共同点?
1.两者最主要的区别在于: sleep()
方法没有释放锁,而 wait()
方法释放了锁 。
2.两者都可以暂停线程的执行。
3.wait()
通常被用于线程间交互/通信, sleep()
通常被用于暂停执行。
4.wait()
方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的 notify()
或者 notifyAll()
方法。 sleep()
方法执行完成后,线程会自动苏醒。或者可以使用 wait(long timeout)
超时后线程会自动苏醒。