Литерал - это специальный синтаксис, который компилятор непосредственно понимает как значение, в отличие от того, что он производит значение с использованием некоторых операций. В отличие от, например, 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
, «постоянная нагрузки»).
Наконец, «литерал» не противопоставляется «объекту», а «не-буквальному» - оцениваемому значению. Противоположностью «объекта» в 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
)