|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Следующие примеры показывают типичные ошибки, с которыми можно встретиться когда размышляющий над классами.
Когда метод вызывается, типы значений аргументов проверяются и возможно преобразовываются. вызывает ClassWarninggetMethod() вызвать типичное преобразование непроверенное, предупреждающее:
import java.lang.reflect.Method;
public class ClassWarning {
void m() {
try {
Class c = ClassWarning.class;
Method m = c.getMethod("m"); // warning
// production code should handle this exception more gracefully
} catch (NoSuchMethodException x) {
x.printStackTrace();
}
}
}
$ javac ClassWarning.java
Note: ClassWarning.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ javac -Xlint:unchecked ClassWarning.java
ClassWarning.java:6: warning: [unchecked] unchecked call to getMethod
(String,Class<?>...) as a member of the raw type Class
Method m = c.getMethod("m"); // warning
^
1 warning
Много методов библиотеки были retrofitted с универсальными объявлениями включая несколько в . С тех пор c объявляется как необработанный тип (не имеет никаких параметров типа), и соответствующий параметр параметризованный тип, преобразование непроверенное происходит. Компилятор обязан генерировать предупреждение. (См. , разделы и .)
Есть два возможных решения. Более предпочтительное это, чтобы изменить объявление c включать соответствующий универсальный тип. В этом случае объявление должно быть:
Class<?> c = warn.getClass();
Альтернативно, предупреждение могло быть явно подавлено, используя предопределенную аннотацию предшествование проблематичному оператору.
Class c = ClassWarning.class;
@SuppressWarnings("unchecked")
Method m = c.getMethod("m");
// warning gone
бросит если попытка предпринимается, чтобы создать новый экземпляр class, и конструктор нулевого параметра не видим.
class Cls {
private Cls() {}
}
public class ClassTrouble {
public static void main(String... args) {
try {
Class<?> c = Class.forName("Cls");
c.newInstance(); // InstantiationException
// production code should handle these exceptions more gracefully
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
}
$ java ClassTrouble
java.lang.IllegalAccessException: Class ClassTrouble can not access a member of
class Cls with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.Class.newInstance0(Class.java:349)
at java.lang.Class.newInstance(Class.java:308)
at ClassTrouble.main(ClassTrouble.java:9)
Class.newInstance() ведет себя очень как new ключевое слово и перестанет работать по тем же самым причинам new перестал бы работать. Типичное решение в отражении состоит в том, чтобы использовать в своих интересах class, который обеспечивает возможность подавить проверки управления доступом; однако, этот подход не будет работать потому что не расширяется . Единственное решение состоит в том, чтобы изменить код, чтобы использовать который действительно расширяется .
Дополнительные примеры потенциального использования задач может быть найден в Конструкторе, Диагностирующем раздел Задействованного урока.