作者:weishu
链接:https://www.zhihu.com/question/67270393/answer/251059300
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
第一个问题,「本地类,成员类,合成类具体是什么概念?」 其实这些名词本身已经说明了他们自己的意思了,写个例子来说明一下到底何种情况对应这些概念:
public class ClassTest {
static class StaticMemberClass {
int a = print(getClass());
}
public class MemberClass {
int a = print(getClass());
}
public static void main(String[] args) {
// 匿名类
new Cloneable() {
int a = print(getClass());
};
// 成员类
new ClassTest().new MemberClass();
// 静态成员类
new StaticMemberClass();
// 局部类
class LocalClass {
int a = print(getClass());
}
new LocalClass();
final Object proxyInstance = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Cloneable.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
print(proxyInstance.getClass());
for (Field field : MemberClass.class.getDeclaredFields()) {
System.out.println(String.format("%s isSynthetic: %s", field.getName(), field.isSynthetic()));
}
}
private static int print(Class<?> clazz) {
System.out.println(String.format("%s isMemberClass : %s", clazz.getName(), clazz.isMemberClass()));
System.out.println(String.format("%s isLocalClass : %s", clazz.getName(), clazz.isLocalClass()));
System.out.println(String.format("%s isAnonymousClass : %s", clazz.getName(), clazz.isAnonymousClass()));
System.out.println(String.format("%s isSynthetic: %s", clazz.getName(), clazz.isSynthetic()));
System.out.println("-----------------------------");
return 0; // 返回值没有用,就为了在成员创建的时候可以调用此函数
}
}
上面代码的输出如下:
me.weishu.epic.test.ClassTest$1 isMemberClass : false
me.weishu.epic.test.ClassTest$1 isLocalClass : false
me.weishu.epic.test.ClassTest$1 isAnonymousClass : true
me.weishu.epic.test.ClassTest$1 isSynthetic: false-----------------------------me.weishu.epic.test.ClassTest$MemberClass isMemberClass : true
me.weishu.epic.test.ClassTest$MemberClass isLocalClass : false
me.weishu.epic.test.ClassTest$MemberClass isAnonymousClass : false
me.weishu.epic.test.ClassTest$MemberClass isSynthetic: false-----------------------------me.weishu.epic.test.ClassTest$StaticMemberClass isMemberClass : true
me.weishu.epic.test.ClassTest$StaticMemberClass isLocalClass : false
me.weishu.epic.test.ClassTest$StaticMemberClass isAnonymousClass : false
me.weishu.epic.test.ClassTest$StaticMemberClass isSynthetic: false--------------------------
me.weishu.epic.test.ClassTest$1LocalClass isMemberClass : false
me.weishu.epic.test.ClassTest$1LocalClass isLocalClass : true
me.weishu.epic.test.ClassTest$1LocalClass isAnonymousClass : false
me.weishu.epic.test.ClassTest$1LocalClass isSynthetic: false---------------------------com.sun.proxy.$Proxy0 isMemberClass : falsecom.sun.proxy.$Proxy0 isLocalClass : false
com.sun.proxy.$Proxy0 isAnonymousClass : falsecom.sun.proxy.$Proxy0 isSynthetic: false-------a isSynthetic: falsethis$0 isSynthetic: true
上面的例子很清楚了,成员类是内部类的子集。
内部类包含四种:静态内部类,成员内部类(非静态内部类),局部内部类,匿名内部类。
合成类没怎么见过,合成方法倒是有很多,比如非静态成员类里面,为了访问外部类的成员,编译器会给它生成一个额外的成员,这个Field就是 “Synthetic”。
第二个问题,“Class应该是JVM预先加载好的对象“ 这句话不对。
Class本质上也是一个对象,对象什么时候可以创建?当然是Runtime启动之后的任何时候。Class对象确实是在运行时动态创建的(除了某些虚拟机内部使用的类型会预先创建)。具体是什么东西创建的呢?ClassLoader。ClassLoader可以通过各种姿势创建Class对象,从本地的jar包中创建,从内存中直接创建,从网络中下载class文件创建。。。除了从文件,内存,网络中通过加载class文件来创建Class对象,Class还可以在运行时动态产生。比如Java的动态代理机制,可以在运行时直接创建出一个全新的Class对象。还有一些第三方的库,比如asm,cglib等,都可以动态创建Class。
回到问题:
1。 那么数组的Class对象到底是什么样的存在? 跟普通的类对象一样,代表对象元数据的存在。
2。 每个类都可以通过数组维度的增加产生无数个不同的Class对象?事实如此。
3。 那JVM怎么预先加载Class对象,还是说Class对象其实是用的时候才产生的?有一些Bootstrap的Class对象是预先加载的,这并非本题的讨论范围之内;其余大部分的Class对象是在用的时候产生的。