Proxypublic class Proxy extends Object implements Serializable{@code Proxy} defines methods for creating dynamic proxy classes and instances.
A proxy class implements a declared set of interfaces and delegates method
invocations to an {@code InvocationHandler}. |
Fields Summary |
---|
private static final long | serialVersionUID | private static final Map | loaderCache | private static final Map | proxyCache | private static int | NextClassNameIndex | protected InvocationHandler | hThe invocation handler on which the method calls are dispatched. |
Constructors Summary |
---|
private Proxy()
| protected Proxy(InvocationHandler h)Constructs a new {@code Proxy} instance with the specified invocation
handler.
this.h = h;
|
Methods Summary |
---|
private static native void | constructorPrototype(java.lang.reflect.InvocationHandler h)
| private static native java.lang.Class | generateProxy(java.lang.String name, java.lang.Class[] interfaces, java.lang.ClassLoader loader)
| public static java.lang.reflect.InvocationHandler | getInvocationHandler(java.lang.Object proxy)Returns the invocation handler of the specified proxy instance.
if (isProxyClass(proxy.getClass())) {
return ((Proxy) proxy).h;
}
throw new IllegalArgumentException(Msg.getString("K00f1")); //$NON-NLS-1$
| public static java.lang.Class | getProxyClass(java.lang.ClassLoader loader, java.lang.Class interfaces)Returns the dynamically built {@code Class} for the specified interfaces.
Creates a new {@code Class} when necessary. The order of the interfaces
is relevant. Invocations of this method with the same interfaces but
different order result in different generated classes. The interfaces
must be visible from the supplied class loader; no duplicates are
permitted. All non-public interfaces must be defined in the same package.
// BEGIN android-note
// Changed parameter to be closer to the RI
// END android-note
// check that interfaces are a valid array of visible interfaces
if (interfaces == null) {
throw new NullPointerException();
}
String commonPackageName = null;
for (int i = 0, length = interfaces.length; i < length; i++) {
Class<?> next = interfaces[i];
if (next == null) {
throw new NullPointerException();
}
String name = next.getName();
if (!next.isInterface()) {
throw new IllegalArgumentException(Msg.getString("K00ed", name)); //$NON-NLS-1$
}
if (loader != next.getClassLoader()) {
try {
if (next != Class.forName(name, false, loader)) {
throw new IllegalArgumentException(Msg.getString(
"K00ee", name)); //$NON-NLS-1$
}
} catch (ClassNotFoundException ex) {
throw new IllegalArgumentException(Msg.getString("K00ee", //$NON-NLS-1$
name));
}
}
for (int j = i + 1; j < length; j++) {
if (next == interfaces[j]) {
throw new IllegalArgumentException(Msg.getString("K00ef", //$NON-NLS-1$
name));
}
}
if (!Modifier.isPublic(next.getModifiers())) {
int last = name.lastIndexOf('.");
String p = last == -1 ? "" : name.substring(0, last); //$NON-NLS-1$
if (commonPackageName == null) {
commonPackageName = p;
} else if (!commonPackageName.equals(p)) {
throw new IllegalArgumentException(Msg.getString("K00f0")); //$NON-NLS-1$
}
}
}
// search cache for matching proxy class using the class loader
synchronized (loaderCache) {
Map<String, WeakReference<Class<?>>> interfaceCache = loaderCache
.get(loader);
if (interfaceCache == null) {
loaderCache
.put(
loader,
(interfaceCache = new HashMap<String, WeakReference<Class<?>>>()));
}
String interfaceKey = ""; //$NON-NLS-1$
if (interfaces.length == 1) {
interfaceKey = interfaces[0].getName();
} else {
StringBuilder names = new StringBuilder();
for (int i = 0, length = interfaces.length; i < length; i++) {
names.append(interfaces[i].getName());
names.append(' ");
}
interfaceKey = names.toString();
}
Class<?> newClass;
WeakReference<Class<?>> ref = interfaceCache.get(interfaceKey);
if (ref == null) {
String nextClassName = "$Proxy" + NextClassNameIndex++; //$NON-NLS-1$
if (commonPackageName != null) {
nextClassName = commonPackageName + "." + nextClassName; //$NON-NLS-1$
}
// BEGIN android-changed
//byte[] classFileBytes = ProxyClassFile.generateBytes(
// nextClassName, interfaces);
// END android-changed
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
// BEGIN android-changed
//newClass = defineClassImpl(loader, nextClassName.replace('.',
// '/'), classFileBytes);
newClass = generateProxy(nextClassName.replace('.", '/"),
interfaces, loader);
// END android-changed
// Need a weak reference to the class so it can
// be unloaded if the class loader is discarded
interfaceCache.put(interfaceKey, new WeakReference<Class<?>>(
newClass));
synchronized (proxyCache) {
// the value is unused
proxyCache.put(newClass, ""); //$NON-NLS-1$
}
} else {
newClass = ref.get();
}
return newClass;
}
| public static boolean | isProxyClass(java.lang.Class cl)Indicates whether or not the specified class is a dynamically generated
proxy class.
if (cl == null) {
throw new NullPointerException();
}
synchronized (proxyCache) {
return proxyCache.containsKey(cl);
}
| public static java.lang.Object | newProxyInstance(java.lang.ClassLoader loader, java.lang.Class[] interfaces, java.lang.reflect.InvocationHandler h)Returns an instance of the dynamically built class for the specified
interfaces. Method invocations on the returned instance are forwarded to
the specified invocation handler. The interfaces must be visible from the
supplied class loader; no duplicates are permitted. All non-public
interfaces must be defined in the same package.
if (h == null) {
throw new NullPointerException();
}
try {
return getProxyClass(loader, interfaces).getConstructor(
new Class<?>[] { InvocationHandler.class }).newInstance(
new Object[] { h });
} catch (NoSuchMethodException ex) {
throw (InternalError) (new InternalError(ex.toString())
.initCause(ex));
} catch (IllegalAccessException ex) {
throw (InternalError) (new InternalError(ex.toString())
.initCause(ex));
} catch (InstantiationException ex) {
throw (InternalError) (new InternalError(ex.toString())
.initCause(ex));
} catch (InvocationTargetException ex) {
Throwable target = ex.getTargetException();
throw (InternalError) (new InternalError(target.toString())
.initCause(target));
}
|
|