问题
Can I (using reflection I presume?) create a class with all the same method names as java.lang.Math
and each method just forwards it to Math
?
E.g.
public class MyMath {
public MyMath() {}
public double abs(double a) {
return Math.abs(a);
}
public float abs(float a) {
return Math.abs(a);
}
public int abs(int a) {
return Math.abs(a);
}
...
public double acos(double a) {
return Math.acos(a);
}
...
How could I generate this programmatically?
回答1:
You can do this with reflection to get an instance of class 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();
}
Whether this is a sensible thing to do is another question.
回答2:
Yes, you can. However, not the way you want it to be I'm afraid.
There are some libraries that you can use to generate dynamic classes at runtime (such as cglib). In order to do so, first, you must define an interface that contains every method definition in Math
class.
Here is an example:
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
}
Then, using cglib, you can create a proxy object that delegates all methods to the original Math class:
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));
}
}
This will print out 256.0
to console.
来源:https://stackoverflow.com/questions/65937379/generate-an-instantiable-class-based-on-a-static-class-reflectively