Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.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_Generics_Methods_Delegates - Fatal编程技术网

在java中将对象方法指定为参数

在java中将对象方法指定为参数,java,generics,methods,delegates,Java,Generics,Methods,Delegates,我想创建一些实用方法,我希望它能够在不同的对象上工作,只要它们能够提供一个读/写的整数属性 我知道“标准”方法是: 声明一些接口IProvidesAccessToInteger,该接口具有setInteger和getInteger 声明MyUtility.doSomethingWonderful(IProvidesAccessToInteger obj) 调用obj.setInteger和obj.getInteger 但这有一个非常严重的缺点,那就是它需要所有我想要MyUtility使用的类的合

我想创建一些实用方法,我希望它能够在不同的对象上工作,只要它们能够提供一个读/写的整数属性

我知道“标准”方法是:

  • 声明一些接口
    IProvidesAccessToInteger
    ,该接口具有
    setInteger
    getInteger
  • 声明
    MyUtility.doSomethingWonderful(IProvidesAccessToInteger obj)
  • 调用
    obj.setInteger
    obj.getInteger
  • 但这有一个非常严重的缺点,那就是它需要所有我想要
    MyUtility
    使用的类的合作,不仅如此,即使某些类想要合作
    MyUtility
    也只能
    .doSomethingWonderful()
    到该类的一个预定字段

    我正在寻找一些语法来支持类似于
    MyUtility.doSomethingWonderful(T obj,Method getter,Method setter)
    的东西,可能会以某种方式使用泛型来指定要求
    obj
    有两个方法可以设置并设置一个整数,并且可以在
    obj
    的实例上调用它们

    对不需要对象的静态方法执行类似操作也可能很有趣

    更新: 正如我被指向反射一样,我想澄清一下,我知道使用反射可以完成相近的事情

    然而,由于我不需要在运行时解析实际的接口,我希望JAVA有某种方式来指定某种“接口实现映射”,这样,如果我的需求是一个具有两种方法的对象
    int?()
    void?(int)
    ,我可以指定类似
    .doSomethingWonderful(?obj)
    并对具有
    int getInt()
    void setInt(int)
    的某个object1调用一次,对具有
    int getIntValue()
    void setIntValue(int)的某个其他object2调用一次
    通过在调用中指定
    object
    通过
    getInt
    满足
    getInteger
    的要求,并通过
    setInt
    满足
    setInteger
    的要求,依此类推。可能使用类似于“.doSomethingWonderful((?)object1)的调用语法

    至少在理论上,我认为应该可以在编译时完成所有工作,而不需要任何运行时反射

    也许匿名接口会给它起一个正确的名字


    也就是说,我接受通过反射的运行时解决方案也可能是一种解决方案。

    泛型无法做到这一点

    你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写

    public void doSomethingWonderful(final Object in, final String fieldName) 
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        final Method getter = in.getClass().getMethod("get" + upperCased);
        final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
    
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    
    我假设您使用的是
    int
    而不是
    Integer
    ,在后一种情况下,您需要稍微更改代码

    您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码

    编辑

    Op希望将方法分解为三个重载方法:

    public void doSomethingWonderful(final Object in, final String fieldName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
    }
    
    public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final Method getter = in.getClass().getMethod(getterName);
        final Method setter = in.getClass().getMethod(setterName);
        doSomethingWonderful(in, getter, setter);
    }
    
    public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    

    你不能用泛型来做这件事

    你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写

    public void doSomethingWonderful(final Object in, final String fieldName) 
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        final Method getter = in.getClass().getMethod("get" + upperCased);
        final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
    
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    
    我假设您使用的是
    int
    而不是
    Integer
    ,在后一种情况下,您需要稍微更改代码

    您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码

    编辑

    Op希望将方法分解为三个重载方法:

    public void doSomethingWonderful(final Object in, final String fieldName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
    }
    
    public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final Method getter = in.getClass().getMethod(getterName);
        final Method setter = in.getClass().getMethod(setterName);
        doSomethingWonderful(in, getter, setter);
    }
    
    public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    

    你不能用泛型来做这件事

    你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写

    public void doSomethingWonderful(final Object in, final String fieldName) 
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        final Method getter = in.getClass().getMethod("get" + upperCased);
        final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
    
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    
    我假设您使用的是
    int
    而不是
    Integer
    ,在后一种情况下,您需要稍微更改代码

    您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码

    编辑

    Op希望将方法分解为三个重载方法:

    public void doSomethingWonderful(final Object in, final String fieldName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
    }
    
    public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final Method getter = in.getClass().getMethod(getterName);
        final Method setter = in.getClass().getMethod(setterName);
        doSomethingWonderful(in, getter, setter);
    }
    
    public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    

    你不能用泛型来做这件事

    你可以通过反射来做到这一点。使用诸如的实用程序当然会更容易,但您也可以手工编写

    public void doSomethingWonderful(final Object in, final String fieldName) 
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        final Method getter = in.getClass().getMethod("get" + upperCased);
        final Method setter = in.getClass().getMethod("set" + upperCased, Integer.TYPE);
    
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    
    我假设您使用的是
    int
    而不是
    Integer
    ,在后一种情况下,您需要稍微更改代码

    您可以看到,它抛出了大量异常,我建议将它们全部包装在自定义异常类型中,以简化客户端代码

    编辑

    Op希望将方法分解为三个重载方法:

    public void doSomethingWonderful(final Object in, final String fieldName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final String upperCased = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
        doSomethingWonderful(in, "get" + upperCased, "set" + upperCased);
    }
    
    public void doSomethingWonderful(final Object in, final String getterName, final String setterName)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final Method getter = in.getClass().getMethod(getterName);
        final Method setter = in.getClass().getMethod(setterName);
        doSomethingWonderful(in, getter, setter);
    }
    
    public void doSomethingWonderful(final Object in, final Method getter, final Method setter)
            throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //to invoke getter
        final int val = (int) getter.invoke(in);
    
        //to invoke setter
        setter.invoke(in, val);
    }
    

    你的接受者和接受者是很好的反省范例。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。

    您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。

    您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。

    您的getter和setter是非常典型的反射。但这将带来很大的风险,并失去业绩。面向接口的编程是处理这种情况的非常常见的“标准”。

    最接近您描述的是Java 8。您仍然需要接口,但调用者不需要关心它们,更好的是,对于典型的t