Viselkedésváltozás nem nyilvános felületek új példányainak létrehozásában

A Java 8 bevezet egy viselkedésváltozást az olyan kód esetén, amely Proxy.getProxyClass és a Constructor.newInstance metódust használja egy proxypéldány létrehozásához, ha a hívó nem ugyanabban a futási környezet csomagban van, mint a nem nyilvános proxy felület. A Java 7 változatban ezeknek a metódusoknak a használata hozza létre a proxy osztályt. A Java 8 változatban egy IllegalAccessException kivétellel meghiúsul.

Mivel az elemző nem mindig tudja megállapítani a használt felületeket vagy azok láthatóságát, ez a szabály a Constructor.newInstance(InvocationHandler) minden meghívását megjelöli, kivéve akkor, amikor ezek elérhetőként vannak meghatározva. A szabály nem jelöli meg a Constructor.newInstance(InvocationHandler) metódus azon meghívásait, amelyeket az azonos metódusban megelőzi a következő metódusok meghívása:

Vizsgálja meg a megjelölt kódot, annak eldöntéséhez, hogy a getProxyClass metódus más futási környezet csomagból van-e meghívva, és hogy a proxy felületek között van-e nem nyilvános. Például egy csomag szintű felület, amelyhez nincs megadva a public kulcsszó, nem nyilvános.

Egy proxy osztály létrehozásához a Java 8 változatban használja a következő technikákat:

Ha jelen van egy biztonságkezelő, akkor mindkét megoldáshoz ReflectPermission("newProxyInPackage.{package name}") engedély szükséges egy SecurityException kivétel elkerüléséhez.

A következő példa bemutatja, hogy miként módosíthatja a kódot, ha a proxyClass metódus egy nem nyilvános felületet példányosít:

Eredeti kód:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

Object o=null;

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

1. megoldás:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

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;
}

2. megoldás:
public Object instantiateClass(Class<?> proxyClass, InvocationHandler handler) throws Exception {

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

További információkért tekintse meg a következő osztályok Java dokumentációját: