动态代理设计模式,及实现原理

动态代理模式,前提还是代理模式,只是优化了静态代理的一些不足。

比如,静态代理在一对一关系出现时,创建的代理对象较多,代码量也大,可维护性就会稍差,在一对多的代理关系出现是,可扩展性就更差了。

而动态代理,就是在使用时,才去创建代理类和实例,这样就可以通过一个动态代理类解决创建多个静态代理的问题,更灵活了。

当然动态代理的缺点也是有的,就是相比静态代理直接调用目标对象方法,动态代理效率会低,因为它是通过反射机制,间接调用目标方法的。

 

所以,在讨论动态代理前,需要先说说静态代理,及反射。

 

先说反射,通常对一个类对象执行操作时,都要先知道它是什么类,是做什么的,然后去实例化 对象进行操作。

但是,反射则是一开始不知道要初始化的类是什么,无法使用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());
    }
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值