[英]Why is it called a “Class literal” when it functions more like an object?
例如:
类c = String.class;
上面的语句将变量c分配给对象,如果是这种情况,为什么当类名称像对象一样起作用时,为什么我们将classname.class称为“文字”呢?
该类没有公共构造函数。 取而代之的是,Java虚拟机会在加载类时以及通过在类加载器中调用defineClass方法来自动构造Class对象。
此外,如果您阅读Javadoc,您将看到Class
没有公开任何公共的setter变异方法。
因此, Class
实例不遵循实例化对象的通常周期,并且在大多数情况下无法进行修改。 因此,与通常的Java对象相比, String.class
行为更像是文字值。
文字是一种特殊的语法,编译器直接将其理解为值,而不是使用某些操作来产生值。 与String.CASE_INSENSITIVE_ORDER
相对, String.class
不访问String
类对象的属性-它是 String
类对象。 您可以在反汇编中看到它:
class Test {
public static Class classProperty = Test.class;
public static String stringProperty = "foo";
public static void main(String args[]) {
String a = "bar";
String b = Test.stringProperty;
Class x = Test.class;
Class y = Test.classProperty;
}
}
编译为:
class Test {
public static java.lang.Class classProperty;
public static java.lang.String stringProperty;
Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String bar
2: astore_1
3: getstatic #3 // Field stringProperty:Ljava/lang/String;
6: astore_2
7: ldc #4 // class Test
9: astore_3
10: getstatic #5 // Field classProperty:Ljava/lang/Class;
13: astore 4
15: return
static {};
Code:
0: ldc #4 // class Test
2: putstatic #5 // Field classProperty:Ljava/lang/Class;
5: ldc #6 // String foo
7: putstatic #3 // Field stringProperty:Ljava/lang/String;
10: return
}
在这里,您可以看到Test.stringProperty
和Test.classProperty
用作属性访问器(使用getstatic
),而Test.class
和"bar"
被当作文字处理(直接使用ldc
,“ load constant”加载它们的值)。
最后,“文字”不是与“对象”相对,而是“非文字”-评估值。 Java中“对象”的反义词是“原始”。 这两个是完全独立的轴。 这里有些例子:
1
原始文字(特别是int
) "foo"
-对象文字(特别是String
) 3 - 2
-原始的非文字(虽然,这是一个简单的情况下,以便编译器将预先计算并把它当作字面1
) "fo" + "o"
-非文字对象(同上,编译器会将其优化为文字"foo"
) x + y
(假设x
和y
是int
)-基本的非文字(无法优化掉) x + y
(假设x
和y
是String
)-非文字对象(无法优化) 类似地
Test.class
对象文字(特别是Class
) new Test().getClass()
-一个非文字对象(特别是Class
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.