Spec-Zone .ru
спецификации, руководства, описания, API
|
Есть два отражающих метода для того, чтобы создать экземпляры классов: java.lang.reflect.Constructor.newInstance()
и Class.newInstance()
Class.newInstance()
Constructor.newInstance()
Class.newInstance()
InvocationTargetException
Class.newInstance()
Constructor.newInstance()
private
конструкторы при определенных обстоятельствах.Иногда это может быть требуемым, чтобы получить внутреннее состояние от объекта, который только устанавливается после конструкции. Рассмотрите сценарий, где необходимо получить внутренний набор символов, используемый java.io.Console
Console
набор символов сохранен в частном поле и является не обязательно тем же самым как набором символов значения по умолчанию виртуальной машины Java, возвращенным java.nio.charset.Charset.defaultCharset()
пример показывает, как это могло бы быть достигнуто:ConsoleCharset
import java.io.Console; import java.nio.charset.Charset; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import static java.lang.System.out; public class ConsoleCharset { public static void main(String... args) { Constructor[] ctors = Console.class.getDeclaredConstructors(); Constructor ctor = null; for (int i = 0; i < ctors.length; i++) { ctor = ctors[i]; if (ctor.getGenericParameterTypes().length == 0) break; } try { ctor.setAccessible(true); Console c = (Console)ctor.newInstance(); Field f = c.getClass().getDeclaredField("cs"); f.setAccessible(true); out.format("Console charset : %s%n", f.get(c)); out.format("Charset.defaultCharset(): %s%n", Charset.defaultCharset()); // production code should handle these exceptions more gracefully } catch (InstantiationException x) { x.printStackTrace(); } catch (InvocationTargetException x) { x.printStackTrace(); } catch (IllegalAccessException x) { x.printStackTrace(); } catch (NoSuchFieldException x) { x.printStackTrace(); } } }
Class.newInstance()
только успешно выполнится, если конструктор будет, имеет нулевые параметры и уже доступен. Иначе, необходимо использовать Constructor.newInstance()
Пример выводил для системы Unix:
$ java ConsoleCharset Console charset : ISO-8859-1 Charset.defaultCharset() : ISO-8859-1
Пример выводил для системы Windows:
C:\> java ConsoleCharset Console charset : IBM437 Charset.defaultCharset() : windows-1252
Другое общее применение Constructor.newInstance()
пример находит определенного конструктора единственного параметра и вызывает это:RestoreAliases
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.Set; import static java.lang.System.out; class EmailAliases { private Set<String> aliases; private EmailAliases(HashMap<String, String> h) { aliases = h.keySet(); } public void printKeys() { out.format("Mail keys:%n"); for (String k : aliases) out.format(" %s%n", k); } } public class RestoreAliases { private static Map<String, String> defaultAliases = new HashMap<String, String>(); static { defaultAliases.put("Duke", "duke@i-love-java"); defaultAliases.put("Fang", "fang@evil-jealous-twin"); } public static void main(String... args) { try { Constructor ctor = EmailAliases.class.getDeclaredConstructor(HashMap.class); ctor.setAccessible(true); EmailAliases email = (EmailAliases)ctor.newInstance(defaultAliases); email.printKeys(); // production code should handle these exceptions more gracefully } catch (InstantiationException x) { x.printStackTrace(); } catch (IllegalAccessException x) { x.printStackTrace(); } catch (InvocationTargetException x) { x.printStackTrace(); } catch (NoSuchMethodException x) { x.printStackTrace(); } } }
Этот пример использование Class.getDeclaredConstructor()
найти конструктора с единственным параметром типа java.util.HashMap
HashMap.class
начиная с параметра любому get*Constructor()
метод требует class только в целях типа. Должный true
:
HashMap.class == defaultAliases.getClass()
Пример тогда создает новый экземпляр class, используя этого конструктора с Constructor.newInstance()
$ java RestoreAliases Mail keys: Duke Fang