Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переменная class, как работает переменная class 
V
    Опции темы
Pawl
Дата 14.10.2011, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Уважаемые форумчане, такой вопрос,
Озаботился назначением переменной class: зачем нужна, какого она типа, где находится (в классе Object ее нет, в других - тоже не видел) и вообще, что она делает?
Очень был бы рад простому и доходчивому разъяснению этого вопроса.
Спасибо!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 14.10.2011, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Нет такой переменной. Запись:
Код

SomeClass.class

это просто указание компилятору, что надо взять Class объект описывающий класс SomeClass. Никакой переменной нет.

P.S. Попробуй
Код

int.class



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Samotnik
Дата 14.10.2011, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 8
Всего: 191



быть может речь о ClassPath  ?

Это сообщение отредактировал(а) Samotnik - 14.10.2011, 22:14
PM MAIL   Вверх
Pawl
Дата 15.10.2011, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Цитата(LSD @  14.10.2011,  18:48 Найти цитируемый пост)
это просто указание компилятору, что надо взять Class объект описывающий класс SomeClass. Никакой переменной нет.

т. е. это что-то вроде Class.forName("SomeClass")? Да, я написал System.out.println(int.class); - получилось int. А если написать Class.forName("int"); - получается ошибка ClassNotFoundException. 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
dorogoyIV
Дата 15.10.2011, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



а документацию почитать по "Class", "Class.forName(...)" не судьба?
PM MAIL   Вверх
math64
Дата 15.10.2011, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(Pawl @  15.10.2011,  08:33 Найти цитируемый пост)
т. е. это что-то вроде Class.forName("SomeClass")?

Компилируется в байт-код именно так, но для классов, но не для int.
Поэтому если пропустить jar через обфускатор, который переименует SomeClass в a, код работать не будет.
Такой код выдержит прогон через обфускатор:
Код

final Class someClassClass = new SomeClass.getClass();
final Class someAbstractClassClass = new SomeAbstractClass[0].getClass().getComponentType();


PM   Вверх
Pawl
Дата 16.10.2011, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Цитата(math64 @  15.10.2011,  20:16 Найти цитируемый пост)
Компилируется в байт-код именно так

спасибо за информацию.
Хочу еще уточнить: при вызове метода Class.forName("SomeClass") (документацию по которому я, кстати, читал),  возвращается объект класса Class для класса SomeClass, и при этом происходит инициализация статической части SomeClass. Действительно, если я напишу
Код

class Abs {
    static {
        System.out.println("its worked!");
    }
}

public class Iniz {
    public static void main(String ...args) throws ClassNotFoundException {
        Class c = Class.forName("Abs");
        System.out.println(c);
    }        
}

то этот код при запуске выдаст 
Цитата

its worked!
class Abs

Но если сделать так
Код

class Abs {
    static {
        System.out.println("its worked!");
    }
}

public class Iniz {
    public static void main(String ...args) throws ClassNotFoundException {
        Class<Abs> c = Abs.class;
        System.out.println(c);
    }        
}

то в результате будет просто
Цитата

class Abs

Т. е. получается, что SomeClass.class - это не тоже самое, что Class.forName("SomeClass"). Значит ли это, что в первом случае просто создается объект класса Class для SomeClass, без инициализации статической части SomeClass?


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
math64
Дата 16.10.2011, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Объект не создаётся в любом случае, а только загружается байт-код класса.
Но в первом случае выполняются статичесткая инициализация.
То что SomeClass.class транслируется как Class.forName("SomeClass") я проверял в JDK, в котором не было шаблонных функций. В новых JDK видимо транслируется по-другому, заметь: у тебя Class<Abs> c = Abs.class; а не Class c = Abs.class;

Добавлено через 6 минут и 59 секунд
Вот как транслируется твой пример (javap -c Iniz):
Код

public static void main(java.lang.String[])   throws java.lang.ClassNotFoundException;
  Code:
   0:    ldc_w    #2; //class Abs
   3:    astore_1
   4:    getstatic    #3; //Field java/lang/System.out:Ljava/io/PrintStream;
   7:    aload_1
   8:    invokevirtual    #4; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   11:    return

PM   Вверх
math64
Дата 16.10.2011, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Вот пул констант:
Код

const #1 = Method    #6.#17;    //  java/lang/Object."<init>":()V
const #2 = class    #18;    //  Abs
const #3 = Field    #19.#20;    //  java/lang/System.out:Ljava/io/PrintStream;
const #4 = Method    #21.#22;    //  java/io/PrintStream.println:(Ljava/lang/Object;)V
const #5 = class    #23;    //  Iniz
const #6 = class    #24;    //  java/lang/Object
const #7 = Asciz    <init>;
const #8 = Asciz    ()V;
const #9 = Asciz    Code;
const #10 = Asciz    LineNumberTable;
const #11 = Asciz    main;
const #12 = Asciz    ([Ljava/lang/String;)V;
const #13 = Asciz    Exceptions;
const #14 = class    #25;    //  java/lang/ClassNotFoundException
const #15 = Asciz    SourceFile;
const #16 = Asciz    Iniz.java;
const #17 = NameAndType    #7:#8;//  "<init>":()V
const #18 = Asciz    Abs;
const #19 = class    #26;    //  java/lang/System
const #20 = NameAndType    #27:#28;//  out:Ljava/io/PrintStream;
const #21 = class    #29;    //  java/io/PrintStream
const #22 = NameAndType    #30:#31;//  println:(Ljava/lang/Object;)V
const #23 = Asciz    Iniz;
const #24 = Asciz    java/lang/Object;
const #25 = Asciz    java/lang/ClassNotFoundException;
const #26 = Asciz    java/lang/System;
const #27 = Asciz    out;
const #28 = Asciz    Ljava/io/PrintStream;;
const #29 = Asciz    java/io/PrintStream;
const #30 = Asciz    println;
const #31 = Asciz    (Ljava/lang/Object;)V;


Добавлено через 5 минут и 19 секунд
но класс всё-таки грузится: если удалить Abs.class получишь
Код

Exception in thread "main" java.lang.NoClassDefFoundError: Abs
    at Iniz.main(Iniz.java:9)

PM   Вверх
LSD
Дата 17.10.2011, 10:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Pawl @  15.10.2011,  09:33 Найти цитируемый пост)
А если написать Class.forName("int"); - получается ошибка ClassNotFoundException.

Класс для примитивного типа, так не загрузишь. Там есть специальный метод Class.getPrimitiveClass(), но он приватный для java.lang.

В Class.forName() можно указать, что не надо вызывать инициализацию класса. Эффект будет тот же самый.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Pawl
Дата 17.10.2011, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Спасибо, math64, но всё-же...smile
Цитата(math64 @  16.10.2011,  13:43 Найти цитируемый пост)
Объект не создаётся в любом случае

А как же тогда понимать описание метода forName в JDK-docs?
Цитата

Returns the Class object associated with the class or interface with the given string name

разве Returns the Class object не переводится, как "возвращает объект класса"?
Цитата(math64 @  16.10.2011,  13:43 Найти цитируемый пост)
тебя Class<Abs> c = Abs.class; а не Class c = Abs.class;

если написать Class c = Abs.class; результат останется прежним.
Цитата(math64 @  16.10.2011,  14:01 Найти цитируемый пост)
Exception in thread "main" java.lang.NoClassDefFoundError:

В JDK-docs про NoClassDefFoundError написано: 
Цитата

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found. 

Интересно, что тут значит "definition of the class" (определение класса)?

Добавлено через 5 минут и 33 секунды
Цитата(LSD @  17.10.2011,  10:10 Найти цитируемый пост)
В Class.forName() можно указать, что не надо вызывать инициализацию класса. Эффект будет тот же самый.

согласен, написал Class c = Class.forName("Abs", false, null); получил ClassNotFoundException!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
LSD
Дата 17.10.2011, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(Pawl @  17.10.2011,  11:11 Найти цитируемый пост)
согласен, написал Class c = Class.forName("Abs", false, null); получил ClassNotFoundException! 

Я говорил про случай, когда класс загружается, но не инициализируется, как в случае:
Код

Class<Abs> c = Abs.class;
System.out.println(c);



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
math64
Дата 17.10.2011, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72





Цитата(Pawl @  17.10.2011,  10:11 Найти цитируемый пост)

Цитата
Returns the Class object associated with the class or interface with the given string name

разве Returns the Class object не переводится, как "возвращает объект класса"?

Возвращает объект типа Class, ассоциированный с классом или интерфейсом с заданным строкой name именем.
Я имет ввиду, что не создаётся объект класса, заданого строкой name (объект абстрактного класса или интерфейса, понятно, не может быть создан в любом случае).
Кстати, объект типа Class создаётся только при первом вызове - в дальнейшем код эквивалентен загрузке константы (см. байт-код)
NoClassDefFoundError получишь если файл Abs.class удалён или попорчен - ClassLoader не сможет его загрузить или найти в нём определение класса.

PM   Вверх
Pawl
Дата 17.10.2011, 20:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 7
Всего: 28



Всем Спасибо, теперь стало более понятно!
Цитата(LSD @  17.10.2011,  10:22 Найти цитируемый пост)
Я говорил про случай, когда класс загружается, но не инициализируется

Понял, когда я написал вот так
Код

Class c = Class.forName("Abs", false, Abs.class.getClassLoader());
System.out.println(c);

Получился такой же вывод, как в коде
Код

Class c = Abs.class;
System.out.println(c);




--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
math64
Дата 18.10.2011, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Цитата(Pawl @  17.10.2011,  20:36 Найти цитируемый пост)
Понял, когда я написал вот так
Код

Class c = Class.forName("Abs", false, Abs.class.getClassLoader());
System.out.println(c);

Смысла в таком коде особого нет - ты два раза получаешь объект Class для класса Abs двуми способами - сначала через Abs.class, затем через Class.forName().
В случае, когда текущий класс и класс Abs имеют тот же загрузщик (в обычной ситуации это так), можно так:
Код

Class c = Class.forName("Abs", false, getClass().getClassLoader());
System.out.println(c);



Это сообщение отредактировал(а) math64 - 18.10.2011, 08:04
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0629 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.