【问题标题】:Access interface variables defined in method访问方法中定义的接口变量
【发布时间】:2015-05-20 09:27:03
【问题描述】:

我将粘贴代码然后解释我需要什么。我不知道如何实现这一点,我什至想不出非常适合我的代码的替代方案。

public Transform findById(final int id) {
    final Transform returnTransform = null;

    execute(new IExecutor() {
        Transform returnTransform = null;
        @Override
        public boolean execute(Transform transform) {
            if (transform.getID() == id) {
                returnTransform = transform;
                return true;
            }
            return false;
        }
    });

    return <returnTransform>;
}

我需要的是从接口内部获取变量“returnTransform”并使用它从“findById”方法返回。
我无法在方法中定义变量,因为它必须是最终的才能在方法中访问:我需要更改它。

一种解决方案是直接在类中定义“returnTransform”变量,但这似乎很俗气。任何人的任何其他天才想法?
谢谢:)

【问题讨论】:

    标签: java methods interface


    【解决方案1】:

    你可以定义你自己的接口,它会有返回returnTransform的方法,比如:

    public interface ExecutorWithTransform extends IExecutor {
        public Transform getTransform();
    }
    

    那么你应该在代码中使用这个接口,在创建实例的时候:

    ExecutorWithTransform executor = new ExecutorWithTransform() {
    
        Transform returnTransform = null;
    
        public Transform getTransform() {
            return returnTransform;
        }
    
        @Override
        public boolean execute(Transform transform) {
            if (transform.getID() == id) {
                returnTransform = transform;
                return true;
            }
            return false;
        }
    };
    
    execute(executor);
    
    return executor.getTransform();
    

    此外,还有一个解决方法,它允许您在匿名接口内使用非最终变量。你应该用一些变量持有者包装你的变量,例如,AtomicReference:

    final AtomicReference<Transform> returnTransform = new AtomicReference<>();
    
    execute(new IExecutor() {
        @Override
        public boolean execute(Transform transform) {
            if (transform.getID() == id) {
                returnTransform.set(transform);
                return true;
            }
            return false;
        }
    });
    
    return returnTransform.get();
    

    但这不应该是惯用的方式。

    【讨论】:

    • 老实说,我喜欢“黑客”……但我更喜欢高质量的代码。
    【解决方案2】:

    您可以创建一个本地类,该类包装Transform 变量并为其公开访问器方法。然后您可以使用final 包装器实例,您将被允许更改其内部状态。

    例如:

    public Transform findById(final int id) {
        class Wrapper {
            private Transform returnTransform = null;
    
            Transform getReturnTransorm() { return returnTransform; }
    
            void setReturnTransform(Transform returnTransform) {
                this.returnTransform = returnTransform;
            }
        }
        final Wrapper wrapper = new Wrapper();
        execute(new IExecutor() {
            @Override
            public boolean execute(Transform transform) {
                if (transform.getID() == id) {
                    wrapper.setReturnTransform(transform);
                    return true;
                }
                return false;
            }
        });
    
        return wrapper.getReturnTransform();
    }
    

    【讨论】:

    • 似乎需要更多的代码来实现一些非常简单的东西,但那是 java :P(实际上是 Android)
    • 你可以升级到 Java-8 :)
    • 删除 'Wrapper' 类声明后的 '()',否则效果很好 ;)
    【解决方案3】:

    创建一个实现IExecutor 的类,其中包含一个带有getter 的Transform 类型的字段,并将其设置在execute - 然后您可以将此类的一个对象传递给executegetTransform

    【讨论】:

      猜你喜欢
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2014-03-21
      • 1970-01-01
      相关资源
      最近更新 更多