Вопрос по compiler-warnings, casting, java – Приятно. Это больше похоже на него!

7

од выглядит следующим образом <, / p>

package com.foo;

public class TestComposition {
    public static void main(String[] args) {
        try {
            Class<Foo> fooClass = 
                    (Class<Foo>) Class.forName("Foo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Назначение в блоке «try» приводит к появлению предупреждения

Type safety: Unchecked cast from Class<capture#1-of ?> to 
     Class<Foo>

Почему это?

Ваш Ответ

4   ответа
7

для начала давайте разберемся, где проблема - это в самом актерском составе. Вот более короткий пример:

public class Test {    
    public static void main(String[] args) throws Exception {
        Object x = (Class<Test>) Class.forName("Test");
    }
}

Это все еще имеет ту же проблему. Проблема в том, что актерский состав на самом деле ничего не собирается тестировать - потому что актерский состав будет эффективно преобразован в исходный код.Class тип. ЗаClass<T> это немного более удивительно, потому что на самом деле объектделает знать участвующий класс, но рассмотрим похожую ситуацию:

List<?> list = ... get list from somewhere;
List<String> stringList = (List<String>) list;

Этот актерский состав не собирается проверять, что этодействительно a List<String>потому что эта информация теряется из-застирание типа.

Теперь в вашем случае, на самом деле, есть более простое решение - если вы все равно знаете имя класса во время компиляции, просто используйте:

Class<Foo> fooClass = Foo.class;

Если вы можете предоставить более реалистичный пример, где этоне В этом случае мы можем помочь вам определить наиболее подходящую альтернативу.

@ Питер Лори - я думаю, я понимаю, что ты имеешь в виду. Почему бы просто не создать экземпляр Foo вместо этого ... Joeblackdev
@Joeblackdev: Это потому, что ввремя исполнения объекты не имеют такой информации общего типа в общем. Если вы позвонитеgetClass() наArrayList<String> это будет то же значение, как если бы вы вызываете его наArrayList<Integer>. Jon Skeet
Я думаю, что настоящая проблема в том, Зачем использовать Class.forName (), если вы знаете тип? Peter Lawrey
Это потому, что это операция во время выполнения? Итак, квинтэссенция заключается в том, что во время компиляции '(Class <Test>)' является излишним, потому что «типы» удаляются компилятором после компиляции - компилятор не может знать, будет ли загруженный класс «Test»? Joeblackdev
@Peter: Ну, эточасть проблемы (как я уже упоминал в своем посте), но это, возможно, было получено из более сложного примера, который имеет больше смысла. Стоит понять принципы, стоящие за предупреждением, ИМО. Jon Skeet
33

Class.forName. Foo.class Сделаю. (До J2SE 5.0,Foo.class на самом деле скомпилировано делатьClass.forName("Foo") а потом кешируем в статике.)

То, что вы, вероятно, хотите, это что-то вроде:

Class<? extends Foo> fooClass =
    (Class<? extends Foo>) Class.forName("MyFoo");

(Когда я говорю «хочу», броски и, в частности, отражение - это зло.)

Как это бывает, у вас есть подходящий способ сделать бросок «безопасно» (при условии,Foo сам по себе не является общим). Безопасно, как если бы вы не предоставили ссылку на несовместимый объект, а не то, что здесь нет ошибок или неожиданных исключений.

Class<? extends Foo> fooClass =
    Class.forName("MyFoo").asSubclass(Foo.class);
Здорово! Спасибо. Это то, что я хочу. Afriza N. Arief
1

вам не нужно было бы использовать Class.forName

Class<Foo> fooClass = Foo.class;

Это имеет смысл делать только тогда, когда вы не знаете тип.

Приятно. Это больше похоже на него! Joeblackdev
2

оверять, что что-то имеет типClass, не если это типаClass<Test>, Вот о чем предупреждение.

Метод был специально добавлен кClass класс, чтобы избежать этого предупреждения. Вы можете использовать это вместо того, чтобы использовать себя:http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class)

Похожие вопросы