Modificarea comportamentului în crearea noii instanţe pentru interfeţe non-publice

Java 8 introduce o modificare de comportament pentru codul care utilizează metodele Proxy.getProxyClass şi Constructor.newInstance pentru a crea o instanţă proxy dacă apelantul nu este în acelaşi pachet de rulare cu interfaţa proxy non-publică. În Java 7, utilizarea acestor metode creează clasa proxy. În Java 8, eşuează cu o IllegalAccessException.

Deoarece analizorul nu poate întotdeauna determina interfeţele care sunt utilizate sau vizibilitatea lor, această regulă semnalează toate invocările Constructor.newInstance(InvocationHandler) cu excepţia cazurilor când sunt definite ca accesibile. Regula nu semnalează invocările metodei Constructor.newInstance(InvocationHandler) care sunt precedate în aceeaşi metodă cu apeluri la următoarele metode:

Inspectaţi codul semnalat pentru a vedea dacă metoda getProxyClass este apelată din alte pachete de runtime dacă o interfaţă proxy este non-publică. De exemplu, o interfaţă la nivel de pachet care nu are cuvântul cheie public este non-publică.

Pentru a crea o clasă proxy în Java 8, utilizaţi una dintre următoarele tehnici:

Dacă este prezent un manager de securitate, ambele soluţii au nevoie de permisiunea ReflectPermission("newProxyInPackage.{nume pachet}") pentru a evita o SecurityException.

Următorul exemplu arată cum puteţi modifica codul dacă metoda proxyClass instanţiază o interfaţă non-publică:

Cod original:
< 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) throws < span class= "JavaType" > Exception < /span> {

Object o=null;

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

Soluţia 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) throws < span class= "JavaType" > Exception < /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;
}

Soluţia 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) throws < span class= "JavaType" > Exception < /span> {

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

Pentru informaţii suplimentare, consultaţi documentaţia Java pentru următoarele clase: