Java 中万物皆对象,Linux 中一切皆文件
先简单的说下对象的实例化过程:
- 首先我们要有个意识,就是创建一个类的实例化对象,内存中必须已经加载了这个类
- 所以,不论是 new 还是反射或是 Unsafe.allocateInstance(Class),都必须要先找到类对象的内存地址
- 然后知道类对象的结构,再去堆上申请新的空间,即实例化对象
- 顺带说下,Java 占内存的原因正是因为对象携带的信息很丰富
Object:万物源头
// new 隐式加载类到内存,再实例化对象
Object obj = new Object();
// Unsafe.allocateInstance
Object obj = Unsafe.allocateInstance(Object.class);
// 手动加载类
// Class.newInstance 是无参构造,最后调用的是 Constructor.newInstance (可带参构造)
Class<String> cls = Class.forName("java.lang.String");
String str = cls.newInstance();
// 其它的还有序列化 clone
复制代码
基础类型的包装类: "="右边可以直接赋值
// 常量池中申请
String str = "string";
// 虚拟机回调 Integer 的静态方法 valueOf(int i) 静态方法说明类已经被加载到内存了
Integer i = 100;
复制代码
数组:一切容器的基础
数组除了 new, 还可以用下面这个静态方法
// Array.newInstance 调用 native 方法 构造一个长度 16 的 int 数组
int[] o = (int[]) Array.newInstance(int.class, 16); // 一维
// 以下都是可以成功构造的 无非是数组嵌套数组
// int[][] o = (int[][]) Array.newInstance(int[].class, 16); // 二维
// int[][][] o = (int[][][]) Array.newInstance(int[][].class, 16); // 三维
复制代码
如下图:
- 该方法还是有一些框架使用到的
- 对于传入的的类型和数组的维度是有限制的,维度限制可能和 byte 有关吧
总结一下
不论是以哪一种方式去实例化对象,我们要明白的是,实例化一个对象之前,内存中必须要有一个类对象,或者说 Class 被加载到内存