浅拷贝 和 深拷贝
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
包装数据类型占用字节数
除了布尔类型,其他类型都可以通过BYTES属性获得占用字节数。
包装类和基本数据类型的对象关系
包装数据类型的缓存机制和装箱拆箱
那些包装类有缓存?
除了 Float 、 Double 、 Boolean 三个包装类没有缓存,其他的如截图所示。
以 Integet 为例分析缓存以及装箱拆箱的过程
在缓存范围内,除了new出一个新对象,其他的都是从缓存中取值。
使用 jad 反编译class文件得到源代码。关于 jad 的下载和安装可以参考另一篇文章。java设计模式-单例模式
得到结论,Integer i1 = 100 实际上 Integer i1 = Integer.valueOf(100),装箱拆箱的过程是语法糖。
拆箱:将 Integer 转化为 int 进行运算。
装箱:将 int 转化为 Integer 进行运算。
根据上面 jad 反编译最后四行的结果可以得到,拆箱会执行 intValue这个方法,而装箱会执行Integer.valueOf方法。
修改缓存最大值
java -XX:+PrintFlagsFinal -version | findstr AutoBoxCache
VM options
-XX:AutoBoxCacheMax=20000
修改前
修改后
可以看到我们已经增大了缓存值。
关于 -XX:-AggressiveOpts 这一个参数
arguments.cpp 这个文件中有相关的实现。
我们搜索一下默认值为 false
设置 vm参数,开启 AggressiveOpts
-XX:AutoBoxCacheMax=20000
-XX:+AggressiveOpts
可以看到缓存最大值仍然生效了。
所以验证 AggressiveOpts 这一参数不影响 AutoBoxCacheMax 的值上限。
自增自减
public class AutoIncrement {
public static void main(String[] args) {
int a = 1;
System.out.println(--a);
System.out.println(++a);
System.out.println(a--);
System.out.println(a++);
System.out.println(a);
}
}
------
0
1
1
0
1
类初始化
引入父类
class A{
private int i = test();
private static int j = method();
static {
System.out.println(1);
}
A(){
System.out.println(2);
}
{
System.out.println(3);
}
public int test(){
System.out.println(4);
return 1;
}
public static int method(){
System.out.println(5);
return 1;
}
}
class B extends A{
private int i = test();
private static int j = method();
static {
System.out.println(6);
}
B(){
System.out.println(7);
}
{
System.out.println(8);
}
@Override
public int test(){
System.out.println(9);
return 1;
}
public static int method(){
System.out.println(10);
return 1;
}
public static void main(String[] args) {
// B b1 =new B();
// System.out.println("---");
// B b2 =new B();
}
}
初始化子类会先初始化父类,按照静态代码顺序执行,先出现先执行。
同理子类静态代码也遵循先后顺序。
实例初始化
代码块 < 构造方法
子类一定会调用父类构造器
父类代码块和方法按照顺序先后执行,
无参构造最后加载
方法重写和重载
重载:同名方法的入参不同。
重写:子类扩展父类方法中的逻辑处理。
多态机制
public class ManyState {
public static void main(String[] args) {
Map<String, Object> tree = new TreeMap<>();
Map<String, Object> hash = new HashMap<>();
}
}
super和this
final 关键字
表示最终的含义。
修饰方法
final 方法不能被重写。
public final void a() {
System.out.println("a");
}
修饰类
final 类不能被继承
修饰字段
如果不指定构造函数,final修饰的字段必须立刻进行初始化。
public class FinalClass {
final int a;
final String b;
}
指定构造函数后可以跟随对象的创建进行初始化。
public class FinalClass {
final int a;
final String b;
public FinalClass(int a, String b) {
this.a = a;
this.b = b;
}
}
static 关键字
对象
instanceof 和 isAssignableFrom 有什么区别?
- instanceof 是 java 关键字,isAssignableFrom 是 Class类的一个方法。
public native boolean isAssignableFrom(Class<?> cls);
- instanceof 一般用于对象实例的类型转换,防止抛出ClassCastException
在 idea 中输入 inst 会提示用法。
if (args instanceof Object) {
Object o = (Object) args;
}
- isAssignableFrom 针对 class 对象,调用者为父类。一句话调用者是不是参数的父类。
public class Father {}
public class Son extends Father{}
System.out.println(Father.class.isAssignableFrom(Son.class));
System.out.println(Son.class.isAssignableFrom(Father.class));
//
true
false
如果Father是Son的父类,那么Son就可以转换为Father类型。