[toc]
1、如何实现对象克隆
- 实现
Cloneable
接口重写Object
类中的clone()
办法 - 实现
Serializable
接口,通过对象序列化和反序列实现克隆,能够实现真正的深度克隆
@Data
public class RealizeCloneable implements Cloneable {
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {return super.clone();
}
}
public class RealizeSerializable {public RealizeSerializable() {throw new AssertionError();
}
public static <T extends Serializable> T clone(T obj)throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T)ois.readObject();}
}
@Data
class Entity implements Serializable {private String name;}
public class CloneTest {
@SneakyThrows
public static void main(String[] args) {Entity entity = new Entity();
entity.setName("Hello");
Entity clone = RealizeSerializable.clone(entity);
System.out.println(clone.toString());
RealizeCloneable realizeCloneable = new RealizeCloneable();
realizeCloneable.setName("Good");
RealizeCloneable clone2 = (RealizeCloneable)realizeCloneable.clone();
System.out.println(clone2.toString());
}
}
2、拜访修饰符有哪些,优先级,以及区别
Java 中,有 4 种不同的修饰符,其优先级别离是 public > protected > default > private
public:所有类可见
protected:子类,同一个包中的类可见
default:通过一个包中可见
private:只能被本人拜访和批改
3、this 与 super 的区别
super()
和 this()
相似, 区别是,super()
从子类中调用父类的构造方法,this()
在同一类内调用其它办法。
从实质上讲,this
是一个指向本对象的指针, 然而 super
是一个 Java 关键字。
4、并发和并行有什么区别
并发是指某一时间段内,多个事件正在交替执行
并行是真正意义上,一个时刻多个事件正在同时执行
5、抽象类 和 接口 有什么区别
- 抽象类只能单继承,接口能够多实现
- 抽象类能够有构造方法,接口中不能有构造方法
- 抽象类中能够有成员变量,接口中没有成员变量,只有常量(默认就是
public static final
) - 抽象类中能够蕴含非形象办法,在 Java7 之前接口中的办法都是形象的,Java8 后,接口反对非形象办法,default 办法和静态方法等,java9 反对公有办法、公有静态方法
6、Error 和 Exception 有什么区别
Error 和 Exception 都是 Throwable 的子类,用于示意程序呈现不失常的状况,然而区别是
- Error 示意零碎级别的谬误,比如说
stackoverflow
栈溢出 - Excpetion 异样分为 可检查和不可查看异样,可查看异样在源码里显示进行捕获,不可查看异样就是所谓的运行时异样,相似 OOM,
ArrayIndexOutOfBoundsException
数据越界这样
7、try、catch、finally 考查
public class TryDemo {public static void main(String[] args) {System.out.println(test());
}
public static int test() {
try {return 1;} catch (Exception e) {return 2;} finally {System.out.print("3");
}
}
}
执行后果为:3 1
在程序执行到 第 3 行,test()
获取后果之前,test
类中的 finally
代码块优先执行,这个没什么好争执的,大家应该都懂
public class TryDemo {public static void main(String[] args) {System.out.println(test1());
}
public static int test1() {
try {return 2;} finally {return 3;}
}
}
执行后果:3
这里就有个陷阱了,很多人会认为是 3 2
其实不是,在第 7 行,return 2
之前,执行 finally
代码块,后果这老六不按常理出牌,间接抢在前头就返回了,所以这里只有 3
public class TryDemo {public static void main(String[] args) {System.out.println(test1());
}
public static int test1() {
int i = 0;
try {
i = 2;
return i;
} finally {i = 3;}
}
}
执行后果:2
这里预计又有人掉陷阱里去了,咱们晓得 return
之前会执行 finally
,然而 finally
中曾经批改为 3 了,那返回的不应该是 3
吗?其实不然,在执行 finally
之前,JVM 会将 i 的后果保存起来,这里用到了两个指令 iload
、istore
最初返回的也是指令中保留的值,而并不是 finally
中批改后的值!
本文由 mdnice 多平台公布