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

时间:2019-06-06 04:58:54

标签: java literals

例如:

  

Class c = String.class;

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

2 个答案:

答案 0 :(得分:1)

根据Javadoc for java.lang.Class

  

类没有公共构造函数。取而代之的是,Java虚拟机会在加载类时以及通过调用类加载器中的defineClass方法自动构造Class对象。

此外,如果您阅读Javadoc,您会发现Class没有公开任何公共的setter变异方法。

因此Class的实例不遵循实例化对象的通常周期,并且在大多数情况下无法进行修改。因此,String.class的行为比普通的Java对象更像是文字值。

答案 1 :(得分:1)

文字是一种特殊的语法,编译器直接将其理解为值,而不是使用某些操作来产生该值。相对于String.CASE_INSENSITIVE_ORDERString.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,“加载常数”直接加载其值)。


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

  • 1-原始文字(特别是int
  • "foo"-对象文字(特别是String
  • 3 - 2-一种原始的非文字形式(尽管这是一个简单的情况,因此编译器将对其进行预先计算并将其视为文字1
  • "fo" + "o"-非文字对象(同上,编译器会将其优化为文字"foo"
  • x + y(假设xyint)-基本的非文字(无法优化)
  • x + y(假设xyString)-一个非文字对象(无法优化)。

类似

  • Test.class-对象文字(特别是类Class的对象)
  • new Test().getClass()-非文字对象(具体是Class类的对象)