一种方法在几种方法中调用

时间:2015-12-15 15:22:28

标签: java

我有一个看起来像这样的课程:

class A {
    public void method1(){
        iniCall();

        // Do something
        finalCall();
    }

    public void method2(){
        iniCall();

        // Do something different
        finalCall();
    } // ... more methods like this
}

如何简化此iniCallfinalCall以便不要在每个函数(或多个函数)中编写它们?

是否可以执行call(method1)之类的操作,如下所示:

public void call(method){
    iniCall();
    method();
    finalCall();
}

否则,什么是好的选择?

5 个答案:

答案 0 :(得分:12)

修改 我看到我的答案提出了一些问题。

  

Runnable接口应由任何其实例由线程执行的类实现。

因此,创建此接口的实例可能会导致不确定性和问题。正如评论中所建议的那样,您可能希望编写自己的界面并使用它。它可能是这样的:

public interface Method {
    public void run();
}

您的call方法将更改为以下内容:

public void call(Method method) {
    iniCall();
    method.run();
    finalCall();
}

你对这种方法的调用将是这样的:

call(new Method() {
    public void run() {
        // do your stuff here
    }
});

我建议您使用类似的设计或考虑使用模板模式,这可能需要进行一些重构。

答案 1 :(得分:12)

如果不使用Java 8,可以使用lambda表达式(或实现Runnable的匿名类实例):

public void call(Runnable method){
    iniCall();
    method.run();
    finalCall();
}

...

public void someMethod () {

    call (() -> {
                   // do something
                });
    ...
    call (() -> {
                   // do something different
                });

}

答案 2 :(得分:5)

与其他建议(比我快得多 - 但我总是希望提供正在运行的示例...)类似,我建议传递Runnable实例到一般调用iniCall()的方法,执行Runnable然后调用finalCall()

实际工作可以作为专用的Runnable实例,lambdas或方法引用传递 - 后者显示在这里:

public class RepeatedMethodContents
{
    public static void main(String[] args)
    {
        RepeatedMethodContents r = new RepeatedMethodContents();
        r.callWrapped(r::doSomething);
        r.callWrapped(r::doSomethingDifferent);
    }

    private void callWrapped(Runnable runnable)
    {
        iniCall();
        runnable.run();
        finalCall();
    }

    private void doSomething()
    {
        System.out.println("doSomething");
    }

    private void doSomethingDifferent()
    {
        System.out.println("doSomethingDifferent");
    }

    private void iniCall()
    {
        System.out.println("ini");
    }

    private void finalCall()
    {
        System.out.println("final");
    }

}

根据需要输出:

ini
doSomething
final
ini
doSomethingDifferent
final

顺便说一句:对于像这样的事情,我总是犹豫是否使用反射 。大多数情况下,有一种更简单,更直接,更不容易出错的方式。

答案 3 :(得分:0)

在Java中,您不能将方法作为参数传递。您可以通过Runnable传递:

public void method1() {
    call(new Runnable() {
        @Override
        public void run() {
            //do something
        }
    });
}

public void method2() {
    call(new Runnable() {
        @Override
        public void run() {
            //do something different
        }
    });
}

public void call(Runnable runnable){
    iniCall();
    runnable.run();
    finalCall();
}

但是,我真的不喜欢这种方法。我认为你可以应用模板设计模式。

答案 4 :(得分:0)

我不确定我是否喜欢在其他人使用过的情况下使用Runnable。通常,我认为Runnable是在线程,执行程序服务等中运行的东西。并且支持the documentation

  

Runnable接口应该由任何其实例都要由线程执行的类实现。

但是从头开始做同样的事情真的很简单快捷。我们可以创建一个抽象类来保存您需要的结构:

public abstract class AbstractClass
{
    private void iniCall() { ... } // Could also be abstract

    private void finalCall() { ... } // Could also be abstract

    public void doTheThing()
    {
        iniCall();
        foo();
        finalCall();
    }

    public abstract void foo();
}

当然,你需要提出更好的名字,但这是起点。然后我们有两个选择:实例化通过扩展此类构建的匿名类,或创建一个新的具体类。以下是使用匿名类的示例:

AbstractClass a = new AbstractClass()
    {
        @Override
        public void foo()
        {
            // Place an implementation here.
            method(); // one example, based on the OP.
        }
    };
a.doTheThing();

以下是你如何做一个实际的课程:

public class ConcreteClass extends AbstractClass
{
    @Override
    public void foo()
    {
        // Place an implementation here.
    }
}
ConcreteClass c = new ConcreteClass();
c.doTheThing();

我主要想提出这个问题,以便你可以看看'匿名类'范例,这类似于能够将函数作为参数传递。其他语言有指向函数,委托等的指针 - 这就是Java所具有的。编译器将确保您的匿名类和具体类将具有foo的实现,否则它将无法编译,因此您不能只是去'oops'并忘记实现。