面试【JAVA基础】其他
1、自定义注解
@target
说明了Annotation所修饰的对象范围: constructor、method、field、package、type等等。
@retention
定义了该Annotation被保留的时间长短, source(源文件保留)、class( class保留)、runtime(运行时有效)。
@inherited
某个被标记的类型是被继承的。一个类标记了带有@inherited的注解,那么他的子类也拥有这个注解。
@document
被修饰的注解会生成到javadoc中。
2、内部类
- 内部类分为:成员内部类,匿名内部类,静态内部类,局部内部类。
- 除了静态内部类,其他的内部类不能拥有静态变量或静态方法,因为内部类属于外部类的一个成员变量,先加载外部类在加载内部类。
原因:- 静态变量在类加载的时候需要将符号引用替换为直接引用而此时还没有内部类的对象。
- 内部类无法在没有外部类的实例下直接使用。
2.1、为什么静态内部类可以拥有静态常量
因为静态常量是在编译时期就确定的值,会存入类的常量池,而访问常量池中的常量是不需要加载类的。
2.2、内部类的使用场景
- 达到一个多重继承的效果
- 访问控制,只能通过外部类调用
3、自动拆箱装箱
- 基本类型和引用类型之间的转换。
- 集合类只接受对象。
- 注意包装类的缓存值,Float和Double值没有缓存值,Integer和Long缓存值为-128~127超过之后会自动转换成对象。两个包装类型进行比较时需要用equals。
4、String为什么是final,StringBuilder与StringBuffer的区别
- String定义成final类型表示不能被继承,确保不会在子类中改变语义。
每次对string对象的改变相当于重新生成了一个新的string对象。经常改变的字符串不建议使用String。 - StringBuffer是线程安全的, StringBuilder是非线程安全的。
5、transient
- 被标记的成员变量不参与序列化过程。
- 只能修饰成员变量,不能修饰类和方法。
6、如何进行序列化
- 实现Serializable接口。
- 序列化使用输出流进行writeObject。
- 反序列化使用输入流进行readObject。
7、如何实现对象克隆
- 实现Cloneable接口,并重写clone方法。
- 也可通过序列化方式进行深拷贝
- 一般实际使用过程中我们只需要拷贝对象的属性,通常使用BeanUtils.copy()
这种拷贝都是浅拷贝 - 几种拷贝对象的性能
cglib>Spring>apache, 一般不建议使用apache的因为对象转换会出错,Spring的date类型转换也可能会出错。
8、异常
8.1、Error
系统级别的错误,程序不必处理。出了错误之后只能退出运行。
8.2、Exception
- 需要进行捕捉或者程序处理的异常。
- Exception分为运行时异常和受检异常
RuntimeException包括:空指针异常,数组下标越界,classNotFound,类型转换异常等等。
受检异常指:编译器要求方法必须声明抛出可能发生的受检异常。
9、Object中的finalize方法
如果类中重写了finalize方法,当该类对象被回收时,finalize方法有可能会被触发。
文章首发于:ClawHub的博客