Java 基元泛型方法

发布于 2024-12-01 09:37:48 字数 1902 浏览 2 评论 0原文

我有一个非常有创意的解决方案,允许我的未签名代码通过我的签名库进行所有访问。虽然做法不好,但我担心我没有其他解决方案(除了重写大量代码,然后需要重写回来)。

我有以下类:

public abstract class full {
    public static <T,S,P> S access(final T object, final String function, final P parameter) {
        AccessController.doPrivileged(new PrivilegedAction<S>() {
            @Override
            public S run() {
                try {
                    if (parameter == null) {
                        Class[] argTypes = { };
                        Object passedArgv[] = { };
                        return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
                    } else {
                        Class[] argTypes = { parameter.getClass() };
                        Object passedArgv[] = { parameter };
                        return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
                    }
                } catch (NoSuchMethodException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SecurityException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
            }
        });
        return null;
    }
}

它非常适合返回对象的函数,但不适用于基元。 布尔 bool = full.access(..); 将导致空指针,因为泛型方法无法处理基元。

关于如何采取正确的方法有什么想法吗?

测试:

public static Boolean test() {
    return true;
}

public Main() {
    System.out.println(((Boolean)redirect.full.access(this, "test", null)));
}

I have a very creative solution to allow my unsigned code all access through my signed library. Although bad practice, I fear I have no other solution (except rewriting a lot of code, that then needs to be rewrited back).

I have the following class:

public abstract class full {
    public static <T,S,P> S access(final T object, final String function, final P parameter) {
        AccessController.doPrivileged(new PrivilegedAction<S>() {
            @Override
            public S run() {
                try {
                    if (parameter == null) {
                        Class[] argTypes = { };
                        Object passedArgv[] = { };
                        return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
                    } else {
                        Class[] argTypes = { parameter.getClass() };
                        Object passedArgv[] = { parameter };
                        return (S)object.getClass().getMethod(function, argTypes).invoke(object, passedArgv);
                    }
                } catch (NoSuchMethodException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SecurityException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(full.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
            }
        });
        return null;
    }
}

It works great for functions that return Objects, but not for primitives.
Boolean bool = full.access(..);
will result in a nullpointer, because generic methods can't handle primitives.

Any ideas about how to take the right approach?

To test:

public static Boolean test() {
    return true;
}

public Main() {
    System.out.println(((Boolean)redirect.full.access(this, "test", null)));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伊面 2024-12-08 09:37:48

您收到 NullPointerException 的原因是您始终返回 null。您调用 doPrivileged(...),但仍返回 null。尝试返回 doPrivileged(...) 的输出。从表面上看,自动(取消)装箱在输入和返回的输出上都起作用。

这对我有用(我传入了一个原始 int,并期望一个原始布尔值):

public class ATest
{
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        int i = 5;
        Object equals = new Object();

        boolean b = full.access(i, "equals", equals);

        System.out.println(b);
    }

    public static class full
    {
        public static <T, S, P> S access(final T object, final String function, final P parameter)
        {
            return AccessController.doPrivileged(new PrivilegedAction<S>()
            {
                @Override
                public S run()
                {
                    try
                    {
                        if (parameter == null)
                        {
                            Class[] argTypes = {};
                            Object passedArgv[] = {};
                            return (S) object.getClass().getMethod(function, argTypes)
                                    .invoke(object, passedArgv);
                        }
                        else
                        {
                            Class[] argTypes = { parameter.getClass() };
                            Object passedArgv[] = { parameter };
                            return (S) object.getClass().getMethod(function, argTypes)
                                    .invoke(object, passedArgv);
                        }
                    }
                    catch (NoSuchMethodException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (SecurityException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (IllegalAccessException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (InvocationTargetException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    return null;
                }
            });
        }
    }
}

另一方面,您可以使其更加健壮。当我传入 Integer 而不是 Object 时,找不到 equals 方法,即使它是有效的方法调用。如果您没有找到给定Class的方法,您应该再次检查该类的父类。

The reason you are getting a NullPointerException is because you are always returning null. You call doPrivileged(...), yet null is still returned. Try returning the output of doPrivileged(...). By the looks of things, Auto(un)boxing is working here on both the inputs and the returned outputs.

This worked for me (I passed in a primitive int, and expected a primitive boolean):

public class ATest
{
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        int i = 5;
        Object equals = new Object();

        boolean b = full.access(i, "equals", equals);

        System.out.println(b);
    }

    public static class full
    {
        public static <T, S, P> S access(final T object, final String function, final P parameter)
        {
            return AccessController.doPrivileged(new PrivilegedAction<S>()
            {
                @Override
                public S run()
                {
                    try
                    {
                        if (parameter == null)
                        {
                            Class[] argTypes = {};
                            Object passedArgv[] = {};
                            return (S) object.getClass().getMethod(function, argTypes)
                                    .invoke(object, passedArgv);
                        }
                        else
                        {
                            Class[] argTypes = { parameter.getClass() };
                            Object passedArgv[] = { parameter };
                            return (S) object.getClass().getMethod(function, argTypes)
                                    .invoke(object, passedArgv);
                        }
                    }
                    catch (NoSuchMethodException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (SecurityException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (IllegalAccessException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    catch (InvocationTargetException ex)
                    {
                        Logger.getLogger(full.class.getName()).log(Level.ALL, null, ex);
                    }
                    return null;
                }
            });
        }
    }
}

On another note, you could make this more robust. When I passed in an Integer instead of an Object, the equals method was not found, even though it would have been a valid method call. If you do not find the method with the given Class, you should check again with the classes' parent classes.

柳絮泡泡 2024-12-08 09:37:48

这不就是原始类的用途吗? (布尔值、整数...)我不确定他们是否会这样做,我还没有检查过。

长答案:克隆所有这些方法以返回原语。

或者更短;您可以将所需的原始类型包装在一个对象中,即执行以下操作:

public class MyInt {
    public int intValue;
}

Isn't that what the primitive classes are for? ( Boolean, Integer... ) I'm not sure if they'll do it, I haven't checked.

Long answer : make a clone of all those methods to return primitives.

Or much shorter; you could just wrap the primitive type you want in an object, that is do something like:

public class MyInt {
    public int intValue;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文