Что такое MyClass.class? - PullRequest
       18

Что такое MyClass.class?

0 голосов
/ 29 июня 2009

ниже приведен код, указанный в MainClass.java.

public class MainClass {

    public static void main(String[] args) {

        System.out.println("main started...");

        Class c = MyClass.class ;
                        //this class variable seems to be public static.
                        //But, as it is clearly visible in the MyClass,
                        //no reference variable is declared.
                        //My problem is that from where this class variable
                        //came from.
                        //i also check out the Object.java file, but it also don't
                        //have any public static class variable of Class class
                        //like there is
                        //out (instance of PrintStream class) in System class.
                        //Hope all u mindoverflow guys help me to sort out
                        //this probz.

        try {
            Class.forName( c.getName() ) ;

            System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader());

            System.out.println("classloader of MyClass : " + String.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("main ended...");
    }
}

class MyClass{
    static{
        System.out.println("static block of MyClass class.");
    }
}

Thhx Coobird ... Я нашел статью довольно полезной. :)

Но о литературных знаниях я ограничен только:

int i = 5 ;  //here 5 is an integer literal

float f = 5.6f ;  //here 5.6f is a float literal

единственный не примитивный литературный, я знаю, это

String str = "java" ;   //"java" is a String litereal

и литерал класса, который вы и Джон Скит очень хорошо разъяснили.

есть ли в java больше литералов ???


согласился ... Таким образом, согласно обсуждению, общие литералы подразделяются на: -

  • примитивные литералы
  • строковые литералы
  • буквальный класс
  • 1028 * нуль *

есть ли еще несколько литералов (чтобы сделать список немного длиннее :) )


когда я декомпилирую класс MainClass.class с использованием декомпилятора, два класса Тип статические переменные (может быть coz, я использовал литерал класса 2 раза) автоматически добавляются, но никогда не используются в коде. Кроме того, оба литерала класса напрямую заменены из файла класса, где я использовал их в файле Java.

Мой код: -

public class MainClass {

    public static void main(String[] args) {

        System.out.println("main started...");

        Class c = MyClass.class ;

        try {
            Class.forName( c.getName() ) ;

            System.out.println("classloader of MyClass : " + MyClass.class.getClassLoader());

            System.out.println("classloader of MyClass : " + String.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        System.out.println("main ended...");
    }
}

Код, сгенерированный декомпилятором: -

import java.io.PrintStream;

public class MainClass
{

    public MainClass()
    {
    }

    public static void main(String args[])
    {
        System.out.println("main started...");
        Class c = MyClass;
        try
        {
            Class.forName(c.getName());
            System.out.println((new StringBuilder("classloader of MyClass : ")).append(MyClass.getClassLoader()).toString());
            System.out.println((new StringBuilder("classloader of MyClass : ")).append(java/lang/String.getClassLoader()).toString());
        }
        catch(ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        System.out.println("main ended...");
    }

    static Class class$0;
    static Class class$1;
}

Ответы [ 4 ]

9 голосов
/ 29 июня 2009

Это "литерал класса" - простой способ получить Class<T> для определенного типа.

Подробнее см. раздел 15.8.2 Спецификации языка Java.

Обратите внимание, что это не "поле" класса, это особый кусочек синтаксического сахара.

Из-за стирания типа вы можете столкнуться с интересными ограничениями в отношении дженериков. TypeLiteral, введенный в Guice, дает больше информации и обходного пути.

С точки зрения реализации, это зависит от того, на какую версию байт-кода вы нацелены. Если вы используете -target 1.4 (или ниже), вызов Class.forName() вставляется в ваш код в статическом методе, который вызывается во время инициализации типа. Если вы используете -target 1.5 (или выше), константный пул получает запись "class". Я не знаю деталей того, как это обрабатывается все же.

3 голосов
/ 29 июня 2009

Запись MyClass.class дает объект типа Class<MyClass>.

Итак, в приведенном выше коде, если нужно правильно использовать дженерики, он должен скорее сказать:

Class<MyClass> c = MyClass.class;

или

Class<?> c = MyClass.class;

Ключевое слово class даст объект Class, который моделирует класс.

Как упоминал Джон Скит, Раздел 15.8.2: Литералы класса из В спецификации языка Java говорится следующее о литерале класса:

Литерал класса - это выражение состоящий из названия класса, интерфейс, массив или примитивный тип, или пустота псевдотипа, сопровождаемая '' и токен class. Тип литерал класса, C.Class, где C - это имя класса, интерфейса или массива тип, Class<C>.

Литерал класса оценивается как объект Class для именованного типа (или для void), как определено определяющим загрузчиком классов класса текущего экземпляра.

0 голосов
/ 29 июня 2009

Правильно, нет, так сказать, переменной экземпляра класса. Это существует в каждом классе, на самом деле. MyClass.class получает экземпляр класса непосредственно для MyClass. Я не уверен, насколько вы знакомы с рефлексией, но это позволяет вам начать работать с этим. Вы можете проверить этот учебник для некоторых примеров того, что вы можете сделать: http://www.ibm.com/developerworks/library/j-dyn0603/

Отражение позволяет программам просматривать и изменять свое поведение во время выполнения. Это тип «метапрограммирования».

0 голосов
/ 29 июня 2009

Чтобы добавить к тому, что уже сказали другие, «MyClass.class» семантически идентичен:

Class.forName("MyClass", false, classloader);

где "classloader" - это экземпляр ClassLoader вызывающего класса.

Основное различие заключается в обработке исключений - с помощью приведенного выше фрагмента кода выдается исключение ClassNotFoundException, но я не верю, что MyClass.class может сгенерировать это (однако, может выдать ClassDefNotFoundError, но это более общая проблема). Кроме того, MyClass.class работает с операторами импорта, тогда как Class.forname () требует, чтобы вы передавали полное имя класса.


Как мне напомнили, MyClass.class не инициализирует MyClass, поэтому статический инициализатор вызываться не будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...