Změna chování ve vytváření nové instance pro neveřejná rozhraní

Java 8 zavádí změnu chování kódu, který používá metody Proxy.getProxyClass a metody Constructor.newInstance k vytvoření instance serveru proxy v případě, že volající není ve stejném balíku běhového prostředí jako neveřejné rozhraní serveru proxy. V prostředí Java 7 vytvoří použití těchto metod třídu proxy. V prostředí Java 8 dojde k nezdaru s výjimkou IllegalAccessException.

Protože analyzátor nemůže vždy určit používaná rozhraní nebo jejich viditelnost, označí toto pravidlo všechna vyvolání objektu Constructor.newInstance(InvocationHandler), s výjimkou případů, kdy jsou tato rozhraní definována jako přístupná. Pravidlo neoznačí vyvolání metody Constructor.newInstance(InvocationHandler), před kterou je uvedena stejná metoda, jako je volání následujících metod:

Zkontrolujte označený kód a zjistěte, zda je metoda getProxyClass volána z jiných balíků běhového prostředí a zda některé z těchto rozhraní proxy není veřejné. Například rozhraní na úrovni balíku, které nemá klíčové slovo public, je neveřejné.

Chcete-li vytvořit třídu proxy v prostředí Java 8, použijte jednu z následujících technik:

Je-li přítomen správce zabezpečení, potřebují obě řešení oprávnění ReflectPermission("newProxyInPackage.{package name}"), abyste se vyhnuli výjimce SecurityException.

Následující příklad ukazuje, jak můžete změnit kód, pokud metoda proxyClass vytváří instanci neveřejného rozhraní:

Původní kód:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Objekt < /span> instantiateClass(< span class= "JavaType"> Třída < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /spanationHandler) vyvolává < span class= "JavaType"> Výjimka < /span> {

Object o=null;

o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
return o;
}

Řešení 1:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Object < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) vyvolává < /span class= "JavaType"> Výjimka < /span> {

Object o=null;

o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
Constructor c = proxyClass.getConstructor(InvocationHandler.class);
c.setAccessible(true);
o = c.newInstance(handler);
return o;
}

Řešení 2:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> Object < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) vyvolává < /span class= "JavaType"> Výjimka < /span> {

Object o=null;
o = Proxy.newProxyInstance(proxyClass.getClassLoader(), proxyClass.getInterfaces(), handler);
return o;
}

Další informace viz dokumentace Java, kde jsou uvedeny následující třídy: