Java 基于静态类反射地生成可实例化类
我是否可以(假设使用反射?)创建一个与Java 基于静态类反射地生成可实例化类,java,reflection,Java,Reflection,我是否可以(假设使用反射?)创建一个与java.lang.Math方法名相同的类,并且每个方法都将其转发给Math 例如 我如何以编程的方式生成它?您可以通过反射来获得类数学的实例: try { Constructor[] cs = Math.class.getDeclaredConstructors(); cs[0].setAccessible(true); Math m = (Math) cs[0].newInstance(); //e.g. Syst
java.lang.Math
方法名相同的类,并且每个方法都将其转发给Math
例如
我如何以编程的方式生成它?您可以通过反射来获得类数学的实例:
try {
Constructor[] cs = Math.class.getDeclaredConstructors();
cs[0].setAccessible(true);
Math m = (Math) cs[0].newInstance();
//e.g.
System.out.println(m.sqrt(16));
}
catch (Exception e) {
e.printStackTrace();
}
这是否明智是另一个问题。您可以通过反射来获得课堂数学的实例:
try {
Constructor[] cs = Math.class.getDeclaredConstructors();
cs[0].setAccessible(true);
Math m = (Math) cs[0].newInstance();
//e.g.
System.out.println(m.sqrt(16));
}
catch (Exception e) {
e.printStackTrace();
}
这是否明智是另一个问题。是的,你可以。然而,恐怕不是你想要的那样 有一些库可用于在运行时生成动态类(例如)。为此,首先,您必须定义一个包含
Math
类中每个方法定义的接口
以下是一个例子:
public interface MathProxy
{
double cos(double a);
double tan(double a);
double log(double a);
double log10(double a);
double sqrt(double a);
double cbrt(double a);
double pow(double a, double b);
double random();
// other methods are listed as well
}
然后,使用cglib,您可以创建一个代理对象,将所有方法委托给原始数学类:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MathEnhancer
{
public static void main(String[] args)
{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MathProxy.class);
enhancer.setCallback(new MethodInterceptor()
{
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
{
Method actualMethod = Math.class.getDeclaredMethod(method.getName(), method.getParameterTypes());
return actualMethod.invoke(null, args);
}
});
MathProxy mathProxy = (MathProxy) enhancer.create();
System.out.println(mathProxy.pow(2, 8));
}
}
这将把
256.0
打印到控制台。是的,您可以。然而,恐怕不是你想要的那样
有一些库可用于在运行时生成动态类(例如)。为此,首先,您必须定义一个包含Math
类中每个方法定义的接口
以下是一个例子:
public interface MathProxy
{
double cos(double a);
double tan(double a);
double log(double a);
double log10(double a);
double sqrt(double a);
double cbrt(double a);
double pow(double a, double b);
double random();
// other methods are listed as well
}
然后,使用cglib,您可以创建一个代理对象,将所有方法委托给原始数学类:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MathEnhancer
{
public static void main(String[] args)
{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MathProxy.class);
enhancer.setCallback(new MethodInterceptor()
{
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
{
Method actualMethod = Math.class.getDeclaredMethod(method.getName(), method.getParameterTypes());
return actualMethod.invoke(null, args);
}
});
MathProxy mathProxy = (MathProxy) enhancer.create();
System.out.println(mathProxy.pow(2, 8));
}
}
这将打印出
256.0
到控制台。您可以使用java.lang.reflect.Proxy
避免奇怪的依赖关系。但正如你所指出的,你无论如何都必须编写接口,所以没有什么意义。这是真的。然而,cglib在许多方面比标准代理类更可取。例如,代理类是java.lang.reflect.Proxy
的子类,而增强类扩展了您指定的任何类型。此外,代理类是最终的。另一方面,您可以根据需要多次扩展增强类,只需使用java.lang.reflect.Proxy
,就可以避免这种奇怪的依赖关系。但正如你所指出的,你无论如何都必须编写接口,所以没有什么意义。这是真的。然而,cglib在许多方面比标准代理类更可取。例如,代理类是java.lang.reflect.Proxy
的子类,而增强类扩展了您指定的任何类型。此外,代理类是最终的。另一方面,您可以根据需要多次扩展增强类。编写一个输出.java
文件的程序。编写一个输出.java
文件的程序。