繁体   English   中英

当它的功能更像对象时,为什么将其称为“类文字”?

[英]Why is it called a “Class literal” when it functions more like an object?

例如:

类c = String.class;

上面的语句将变量c分配给对象,如果是这种情况,为什么当类名称像对象一样起作用时,为什么我们将classname.class称为“文字”呢?

根据Javadoc的java.lang.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.stringPropertyTest.classProperty用作属性访问器(使用getstatic ),而Test.class"bar"被当作​​文字处理(直接使用ldc ,“ load constant”加载它们的值)。


最后,“文字”不是与“对象”相对,而是“非文字”-评估值。 Java中“对象”的反义词是“原始”。 这两个是完全独立的轴。 这里有些例子:

  • 1原始文字(特别是int
  • "foo" -对象文字(特别是String
  • 3 - 2 -原始的非文字(虽然,这是一个简单的情况下,以便编译器将预先计算并把它当作字面1
  • "fo" + "o" -非文字对象(同上,编译器会将其优化为文字"foo"
  • x + y (假设xyint )-基本的非文字(无法优化掉)
  • x + y (假设xyString )-非文字对象(无法优化)

类似地

  • Test.class对象文字(特别是Class
  • new Test().getClass() -一个非文字对象(特别是Class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM