動態代理設計模式,及實現原理

動態代理模式,前提還是代理模式,只是優化了靜態代理的一些不足。

比如,靜態代理在一對一關係出現時,創建的代理對象較多,代碼量也大,可維護性就會稍差,在一對多的代理關係出現是,可擴展性就更差了。

而動態代理,就是在使用時,纔去創建代理類和實例,這樣就可以通過一個動態代理類解決創建多個靜態代理的問題,更靈活了。

當然動態代理的缺點也是有的,就是相比靜態代理直接調用目標對象方法,動態代理效率會低,因爲它是通過反射機制,間接調用目標方法的。

 

所以,在討論動態代理前,需要先說說靜態代理,及反射。

 

先說反射,通常對一個類對象執行操作時,都要先知道它是什麼類,是做什麼的,然後去實例化 對象進行操作。

但是,反射則是一開始不知道要初始化的類是什麼,無法使用new關鍵字來創建對象。而是在運行時才知道要操作的類是什麼,可以在運行時獲取類的完整構造,並調用對應的方法,訪問屬性。

那反射跟運行時類信息(RTTI)有什麼區別呢?

運行時類型識別(Run-Time Type Identification),使得可以在程序運行時發現和使用類型信息。

Java有兩種方式可以讓我們在運行時識別對象和類的信息,一種是RTTI,它假定在編譯時已經知道了所有的類型;另一種就是反射,允許在運行時發現和使用類信息。

RTTI的基本使用

package rtti;
import java.util.Arrays;
import java.util.List;
public class ShapeRtti {	
	
	static abstract class Shape {

		void draw() {
			System.out.println(this + ".draw()");
		}
		abstract public String toString();

	}	
	
	static class Circle extends Shape{

		@Override
		public String toString() {
			return "Circle";
		}
		
	}
	
	
	static class Square extends Shape{

		@Override
		public String toString() {
			return "Square";
		}
		
	}

	public static void main(String[] args) {
		List<Shape> shapeList = Arrays.asList(new Circle(),new Square());
		for (Shape shape : shapeList) {
			shape.draw();
		}
	}
}

/*output*/

Circle.draw()

Square.draw()

在這個例子中,把Circle對象放入List<Shape>數組時會向上轉型,在向上轉型爲Shape時,也丟失了Shape對象的具體類型,對於數組來說,它們只是Shape類的對象。

當從數組取出元素時,會自動轉型會Shape(因爲List實際上把所有事物都當做Object持有),這就是RTTI最基礎的使用形式。在java中,多有的類型轉換都是在運行時進行正確性檢查的,也就是RTTI的含義,在運行時,識別一個對象的類型。

 

在說反射,Class類跟java.lang.reflect類庫,一起對反射的概念進行了支持,類庫包含了Field,Method,Constructor類,可以用Constructor創建新的對象,用get,set方法讀取修改Field對象關聯的字段,用invoke方法調用Method對象關聯的方法,用getFieldgetMethodsgetContructor返回表示字段,方法,構造器的對象的數組。當通過反射與一個未知類型的對象打交道時,JVM只是簡單的檢查這個對象,看他屬於哪個特定的類,用他做事情前,必須先加載這個類的class對象,這個類的class文件對於jvm來說必須是可獲取的。

 

RTTI跟反射最根本的區別在於,對於RTTI來說,編譯器在編譯時打開和檢查.class文件,也就是說我們使用普通的方式調用對象的方法,但是對於反射來說,.class文件在編譯時是不可獲取的,而是要在運行時打開和檢查.class文件。

 

Class是一個類,封裝了當前對象所對應的類的信息

一個類中有屬性,方法,構造器等,比如說有一個Person類,一個Order類,一個Book類,這些都是不同的類,現在需要一個類,用來描述類,這就是Class,它應該有類名,屬性,方法,構造器等。Class是用來描述類的類。

Class類是一個對象照鏡子的結果,對象可以看到自己有哪些屬性,方法,構造器,實現了哪些接口等等

對於每個類而言,JRE 都爲其保留一個不變的 Class 類型的對象。一個 Class 對象包含了特定某個類的有關信息。 

對象只能由系統建立對象,一個類(而不是一個對象)在 JVM 中只會有一個Class實例

獲取Class對象的三種方式

  1.通過類名獲取      類名.class   

  2.通過對象獲取      對象名.getClass()

  3.通過全類名獲取    Class.forName(全類名)

Class類的常用方法

然後說,靜態代理模式:爲其他對象提供一種代理,以控制對這個對象的訪問。

代理模式結構圖

其中有抽象主題Subject,真實主題RealSubject,代理Proxy,

Subject定義了RealSubject,Proxy共用接口,在任何使用RealSubject的地方都可以使用Proxy。

RealSubject定義了Proxy代表的真實主題。

Proxy保存一個真實主題的引用,使得代理可以訪問真實主題,並提供了跟Subject相同的接口,這樣就可以代替真實主題。

 

RealSubject,Proxy跟Subject是繼承關係,而Proxy需要知道它代理的真實主題,所以跟RealSubject是關聯關係。

代理模式的實現代碼。

package simplePry;

public class SimpleProxyRun {

	public SimpleProxyRun() {
	}
	
	public static void consumer(ProxyInterface pi) {
		pi.doSomething();
		pi.somethingElse("help me do.....");
	}

	public static void main(String[] args) {
		consumer(new RealObject());
		System.out.println("-----------------");
		consumer(new SimpleProxy(new RealObject()));
	}
}
package simplePry;

public class RealObject implements ProxyInterface {

	public RealObject() {
		System.out.println("realObject");
	}

	@Override
	public void doSomething() {
		System.out.println("realObject,do Something");

	}

	@Override
	public void somethingElse(String args) {
		System.out.println("realObject,somethingElse "+ args);
	}
}
package simplePry;

public class SimpleProxy implements ProxyInterface {
	private ProxyInterface mProxy;
	public SimpleProxy(ProxyInterface proxy) {
		mProxy = proxy;
		System.out.println("SimpleProxy,mProxy="+mProxy);
	}

	@Override
	public void doSomething() {
		System.out.println("SimpleProxy,do Something");
		mProxy.doSomething();

	}

	@Override
	public void somethingElse(String args) {
		System.out.println("SimpleProxy,somethingElse "+ args);
		mProxy.somethingElse(args);
	}
}
public class SimpleProxyRun {

	public SimpleProxyRun() {
	}
	
	public static void consumer(ProxyInterface pi) {
		pi.doSomething();
		pi.somethingElse("help me do.....");
	}

	public static void main(String[] args) {
		consumer(new RealObject());
		System.out.println("-----------------");
		consumer(new SimpleProxy(new RealObject()));
	}
}

/*output*/

realObject

realObject,do Something

realObject,somethingElse help me do.....

-----------------

realObject

SimpleProxy,mProxy=simplePry.RealObject@15db9742

SimpleProxy,do Something

realObject,do Something

SimpleProxy,somethingElse help me do.....

realObject,somethingElse help me do.....

例子中,consumer接受的是ProxyInterface,它無法知道正在獲得的到底是RealObject還是SimpleProxy。但是SimpleProxy被插入到了客戶端和RealObject之間,所以他會執行操作,然後調用RealObject上相同的方法。

 

動態代理比靜態代理的思想又向前了一步,因爲他可以動態的創建代理並動態的處理對所代理方法的調用,在動態代理上所做的所有調用都會被重定向到單一的調用處理器上,它的任務就是揭示調用的類型,然後確定響應的對策。

動態代理中所謂的動態,是針對使用java代碼實際編寫了代理類的靜態代理而言的。它的優勢不在於省去了編寫代理類那一點工作量,而是實現了可以在原始類和接口還未知的時候,就確定代理類的代理行爲,當代理類與原始類脫離直接關係後,就可以靈活重用與不同的應用場景中。

下面用動態代理重寫上例。

package simpleDynamicPry;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicProxyHandler implements InvocationHandler {
	private Object proxied;
	
	public DynamicProxyHandler(Object proxied) {
		this.proxied = proxied;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("-----proxy:" + proxy.getClass() +
				",method:" + method +
				",args :" + args);
		
		if (args != null) {
			for (Object arg : args) {
				System.out.println(" " + arg);
			}
		}
		return method.invoke(proxied, args);
	}
}
package simpleDynamicPry;

import java.lang.reflect.Proxy;

import simplePry.ProxyInterface;
import simplePry.RealObject;

public class SimpleDynamicProxy {

	public SimpleDynamicProxy() {
	}

	public static void consumer(ProxyInterface pi) {
		pi.doSomething();
		pi.somethingElse(" dynamic proxy.");
	}
	
	public static void main(String[] args) {
		RealObject real = new RealObject();
		consumer(real);
		//ProxyInterface.class.getClassLoader(),
		//new Class[] {ProxyInterface.class},
		ProxyInterface pi = (ProxyInterface)Proxy.newProxyInstance(
				real.getClass().getClassLoader(),
				real.getClass().getInterfaces(),
				new DynamicProxyHandler(real));
		consumer(pi);
	}
}

/*output*/

realObject

realObject,do Something

realObject,somethingElse  dynamic proxy.

**********************

-----proxy:class com.sun.proxy.$Proxy0,method:public abstract void simplePry.ProxyInterface.doSomething(),args :null

realObject,do Something

-----proxy:class com.sun.proxy.$Proxy0,method:public abstract void simplePry.ProxyInterface.somethingElse(java.lang.String),args :[Ljava.lang.Object;@6bc7c054

  dynamic proxy.

realObject,somethingElse  dynamic proxy.

通過靜態方法Proxy.newProxyInstance創建動態代理,需要一個類加載器,一個希望該代理實現的接口列表(是接口,不是類、抽象類),一個InvocationHandler接口的實現。動態代理可以將所有調用重定向到調用處理器,因此通常會向調用處理器的構造器傳遞一個真實對象的引用,使得調用處理器在執行其中介任務時,可以將請求轉發。

這個Proxy.newProxyInstance()方法,返回的是一個實現了ProxyInterface接口,並且代理了RealObject實例行爲的對象。

 

最後,動態代理的實現原理。

在動態代理的例子中,真實的代理類,代理對象,並沒有看到它的class對象,那麼jdk內部是怎麼實現的呢?

通常,在jdk中,一個類的使用這樣的:

  1. 寫一個java源文件,
  2. 編譯成.class文件,
  3. Jvm通過類加載器生成一個Class對象,
  4. 通過Class對象,獲取到實例對象,

對於動態代理,沒有看到些java源文件的過程,也就是說動態代理類,沒有.class文件。

查看例子生成的class文件,也只看到:

DynamicProxyHandler.class

SimpleDynamicProxy.class

單步debug,可以看到

		ProxyInterface pi = (ProxyInterface)Proxy.newProxyInstance(
				real.getClass().getClassLoader(),
				real.getClass().getInterfaces(),
				new DynamicProxyHandler(real));

這句代碼創建的對象是:$Proxy0

這個類我們沒有寫過,在例子的輸出目錄中也沒有這個Proxy0這個類。

深入源碼:

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
@Proxy.java {
// 前面的常規檢查,不去關注
//	Class是對每個類的一個抽象,
     /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);
//通過class拿到類的構造器,
		final Constructor<?> cons = cl.getConstructor(constructorParams);		
//返回類的一個實例。代理類實例的創建,就是由newInstance來負責的。
		return cons.newInstance(new Object[]{h});
}
//Class<?> cl這個cl,很有可能就是我們沒有寫,由jdk內部幫我們創建的動態代理類。

//繼續跟進getProxyClass0,
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) @ Proxy.java {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
//代理類,jdk是實現時,可能會做緩存
        return proxyClassCache.get(loader, interfaces);
    }

第一次用動態代理時,如果緩存裏沒有,怎麼處理的呢?

繼續看源碼:

public V get(K key, P parameter) @ WeakCache.java{
//這裏會從緩存獲取。
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }
//這裏是真正創建代理類的地方,創建完成後,放入緩存。
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
}

 

分析:subKeyFactory.apply(key, parameter)

//這是一個泛型接口,

R apply(T t, U u)@BiFunction.java

在Proxy.java中有這個接口的具體實現。

private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>> @ Proxy.java{
        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
。。。
	//不去關注別的,僅關注proxy類是怎麼創建的。
                /*
                 * Choose a name for the proxy class to generate.
                 */
//這裏可以看到,我們例子中創建的代理類$Proxy0,這個名字是怎麼來的,
//前綴:private static final String proxyClassNamePrefix = "$Proxy";
//num,是通過CAS的原子操作產生,換句話說,如果我們創建了2個動態代理類,第//二個應該就是$Proxy1
//需要提醒的是,這裏是android源碼庫下的實現,
//openjdk源碼的實現不太一樣,下面給出。
                long num = nextUniqueNumber.getAndIncrement();
                String proxyName = proxyPkg + proxyClassNamePrefix + num;

                return generateProxy(proxyName, interfaces, loader, methodsArray,
                                     exceptionsArray);
}	
}

 修改測試代碼,驗證第二個動態代理類是不是$Proxy1.

public interface ProxyInterface2 {
	void doSomething();
	void somethingElse(String args);
}
public class RealObject2 implements ProxyInterface2 {

	public RealObject2() {
		System.out.println("realObject");
	}

	@Override
	public void doSomething() {
		System.out.println("realObject,do Something");

	}

	@Override
	public void somethingElse(String args) {
		System.out.println("realObject,somethingElse "+ args);
	}
}
public class SimpleDynamicProxy {

	public SimpleDynamicProxy() {
	}

	public static void consumer(ProxyInterface pi) {
		pi.doSomething();
		pi.somethingElse(" dynamic proxy.");
	}
	
	public static void main(String[] args) {
		RealObject real = new RealObject();
		RealObject2 real_2 = new RealObject2();
		consumer(real);
		System.out.println("**********************");
		//ProxyInterface.class.getClassLoader(),
		//new Class[] {ProxyInterface.class},
		ProxyInterface pi = (ProxyInterface)Proxy.newProxyInstance(
				real.getClass().getClassLoader(),
				real.getClass().getInterfaces(),
				new DynamicProxyHandler(real));
		ProxyInterface2 pi_2 = (ProxyInterface2)Proxy.newProxyInstance(
				real_2.getClass().getClassLoader(),
				real_2.getClass().getInterfaces(),
				new DynamicProxyHandler(real_2));		
		consumer(pi);
	}
}

動態代理類

如上圖,通過debug可以看到第二個動態代理類名字是$Proxy1。

在看下openjdk源碼的實現。

private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    @ Proxy.java {
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
            /*
             * Generate the specified proxy class.
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
}
}

Jdk源碼中,代理類先是生成了一個字節數組,然後通過native方法創建了代理類的class,有字節數組,就可以通過流輸出到文件中,看看這個代理類長什麼樣。

但是android源碼中,沒有看到這個字節數組的生成,而是通過class_linker.cc中方法一步步生成,要輸出$proxy不是很容易。

generateProxy是native方法:
static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring name, jobjectArray interfaces,
                                  jobject loader, jobjectArray methods, jobjectArray throws) @ java_lang_reflect_Proxy.cc {
  ScopedFastNativeObjectAccess soa(env);
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  return soa.AddLocalReference<jclass>(class_linker->CreateProxyClass(
      soa, name, interfaces, loader, methods, throws));
}

下面用jdk的源碼實現,把$Proxy0的內容輸出到文件,看看這個類有哪些內容:

只要把源碼實現中:

            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);

這個字節數組保存到文件即可。

public class ProxyUtils {

    public static void generateClassFile(Class clazz,String proxyName){
        /*ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);*/
        byte[] proxyClassFile =ProxyGenerator.generateProxyClass(
                proxyName, new Class[]{clazz});
        String paths = clazz.getResource(".").getPath();
        System.out.println(paths);
        FileOutputStream out = null;

        try {
            out = new FileOutputStream(paths+proxyName+".class");
            out.write(proxyClassFile);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public class SimpleDynamicProxy {

	public static void main(String[] args) {
		RealObject real = new RealObject();
		RealObject2 real_2 = new RealObject2();
		consumer(real);
		System.out.println("**********************");
		//ProxyInterface.class.getClassLoader(),
		//new Class[] {ProxyInterface.class},
		ProxyInterface pi = (ProxyInterface)Proxy.newProxyInstance(
				real.getClass().getClassLoader(),
				real.getClass().getInterfaces(),
				new DynamicProxyHandler(real));
		//添加生成$proxy0文件的調用
        ProxyUtils.generateClassFile(real.getClass(),
        		pi.getClass().getSimpleName());		
	}
}

再次運行後,可以在項目的輸出目錄看到$Proxy0.class文件。

--

藉助反編譯工具JD-GUI,查看這個class文件

通過$Proxy0這個class文件,可以看出動態代理究竟是怎麼實現的。

$Proxy0

 

這個代理類$Proxy0繼承自Proxy,實現了我們自定義的業務接口RealObject,所有的代理類都是繼承自Proxy。從下面Proxy.java的註釋也可以看出。

/**
 * {@code Proxy} provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
*/

繼續看$Proxy0,

 public final void doSomething()
    throws 
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

這個doSomething(),就是我們自定義的接口中的方法。

this.h.invoke(this, m3, null);

這是一個標準的反射機制中的調用。其中的h並不在$Proxy0中,而是在其父類Proxy.java中,

 /**
     * the invocation handler for this proxy instance.
     * @serial
     */
    protected InvocationHandler h;

這個h就是在實現動態代理時,傳入的最後一個參數:

	ProxyInterface pi = (ProxyInterface)Proxy.newProxyInstance(
				real.getClass().getClassLoader(),
				real.getClass().getInterfaces(),
				new DynamicProxyHandler(real));

所以$Proxy0中的invoke調用的就是DynamicProxyHandler.java中的invoke().

其中的方法名m3,是誰呢?

--

Method m3就是通過反射拿到的業務類中定義的doSomething方法。所以invoke實際調用的就是業務類中實現的方法。

這個代理類的實現代碼其實很簡單,它爲接口中的每一個方法,及從java.lang.Object繼承下來的方法如equals(), hashcode()都生成了對應的實現,並且這些實現統一調用InvocationHandler的invoke方法去實現這些方法的內容,各個方法的區別只是傳入的參數和Method對象不同,所以無論調用動態代理的那個方法,實際都是執行InvocationHandler中的invoke的代碼邏輯。

要生成$Proxy0.class這個文件,還可以通過在main()中添加這個屬性:

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

然後會在項目的根目錄下生成這個class文件。

附錄:$Proxy0.class

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import simplePry.RealObject;

public final class $Proxy0 extends Proxy
  implements RealObject
{
  private static Method m1;
  private static Method m3;
  private static Method m9;
  private static Method m2;
  private static Method m4;
  private static Method m7;
  private static Method m6;
  private static Method m8;
  private static Method m10;
  private static Method m0;
  private static Method m5;

  public $Proxy0(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }

  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void doSomething()
    throws 
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void notify()
    throws 
  {
    try
    {
      this.h.invoke(this, m9, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void somethingElse(String paramString)
    throws 
  {
    try
    {
      this.h.invoke(this, m4, new Object[] { paramString });
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait(long paramLong)
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m7, new Object[] { Long.valueOf(paramLong) });
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait(long paramLong, int paramInt)
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m6, new Object[] { Long.valueOf(paramLong), Integer.valueOf(paramInt) });
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final Class getClass()
    throws 
  {
    try
    {
      return (Class)this.h.invoke(this, m8, null);
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void notifyAll()
    throws 
  {
    try
    {
      this.h.invoke(this, m10, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void wait()
    throws InterruptedException
  {
    try
    {
      this.h.invoke(this, m5, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m3 = Class.forName("simplePry.RealObject").getMethod("doSomething", new Class[0]);
      m9 = Class.forName("simplePry.RealObject").getMethod("notify", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      m4 = Class.forName("simplePry.RealObject").getMethod("somethingElse", new Class[] { Class.forName("java.lang.String") });
      m7 = Class.forName("simplePry.RealObject").getMethod("wait", new Class[] { Long.TYPE });
      m6 = Class.forName("simplePry.RealObject").getMethod("wait", new Class[] { Long.TYPE, Integer.TYPE });
      m8 = Class.forName("simplePry.RealObject").getMethod("getClass", new Class[0]);
      m10 = Class.forName("simplePry.RealObject").getMethod("notifyAll", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m5 = Class.forName("simplePry.RealObject").getMethod("wait", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章