Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于静态类反射地生成可实例化类_Java_Reflection - Fatal编程技术网

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
文件的程序。