确定一个方法是第一次调用还是第二次调用?

4
我想实现一个方法,当第一次调用时会有不同的行为,而第二次调用时则有不同的行为。如何实现?

4
将一个静态整型设为计数器。 - Scary Wombat
1
使用标志并且如果你想要计数,使用计数器。 - techprat
6个回答

6

Java中的实例方法可以访问类的状态。添加一个变量来指示方法是否被调用过,并使用它来决定方法内部要采取哪条路径:

class FirstTimeCaller {
    private boolean isFirstTime = true;
    void methodWithState() {
        if (isFirstTime) {
            ... // Do first-time thing
            isFirstTime = false;
        } else {
            ... // Do the other thing
        }
    }
}

这适用于同一对象的实例方法:首次调用将在每个FirstTimeCaller类的新对象上第一次调用methodWithState时执行。
如果您希望为静态方法实现相同的行为,或者希望对任何实例的第一次调用执行不同的操作,并且所有后续调用执行其他操作,请将isFirstTime字段设置为static

2
您可以简单地创建一个变量。
int counter = 0; // This means the method has not been called yet

当该方法被调用时,请执行以下代码:

counter++; // Increment by 1 for each new call

你有一些存储在变量“counter”中的方法调用,因此您可以选择如何处理它。


2

为了扩展可能的解决方案列表,您也可以考虑使用状态模式

public class Sandbox {

    private Runnable delegate = () -> {
        System.out.println("First Time");
        delegate = () -> System.out.println("Second Time");
    };

    public synchronized void doIt() {
        delegate.run();
    }
}

1
public class MethodLogic implements Callable<String> {
    private boolean called = false;

    public String call() {
        if (!called) {
            called = true;
            return "first";
        } else {
            return "not first";
        }
    }
}

稍后使用它,如下所示:
Callable<String> method = new MethodLogic();
System.out.println(method.call());
System.out.println(method.call());

1

如果在多线程环境中调用,您必须小心处理并发访问。例如,您可以使用AtomicBoolean:

public class FirstAndSecondTime {

    private static final AtomicBoolean FIRST_TIME = new AtomicBoolean(true);

    public void perform() {
        if (FIRST_TIME.compareAndSet(true, false)) {
            //execute first time logic here
        } else {
            //execute 2-n time logic here
        }
    }

}

1
使用静态类:
public class MyStaticClass {
private static boolean firstTime = true;

public static void myMethod() {
    if (firstTime) {
        System.out.println("First time");
    } else {
        firstTime = false;
        System.out.println("NOT first time");
    }
}

}

然后您可以这样使用它:
MyStaticClass.myMethod(); //-> prints "First time"
MyStaticClass.myMethod(); //-> prints "NOT first time"
MyStaticClass.myMethod(); //-> prints "NOT first time"

这就是单例模式使用懒加载实现的方式:
public final class Singleton {
private static Singleton instance = null;

private Singleton() {}

public static Singleton getInstance() {
    if (instance == null) {
        if (instance == null) {
            instance = new Singleton();
        }
    }
    return instance;
}

}

除非你在使用单例模式,否则最好不要使用这个(我猜想),而是在对象上使用一个字段:

public class MyMessagePrinter {
private int counter = 0;

public void printMessage() {
    if (this.counter > 0) {
        System.out.println("Fist time");
    } else {
        System.out.println("NOT first time");
    }
}
}

像这样使用:

MyMessagePrinter myPrinter = new MyMessagePrinter();
myPrinter.print(); //-> prints "First time"
myPrinter.print(); //-> prints "NOT first time"
myPrinter.print(); //-> prints "NOT first time"

请注意,该代码不是线程安全的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接