Java 重置可变类字段

Java 重置可变类字段,java,class,java-8,Java,Class,Java 8,假设我有一个具有一些可变字段的类: public class Test { private boolean isCorrect; private String userId; public void run() {...} // more methods } run()方法将修改这些字段。我的问题是该类的调用方可能多次调用run(),因此我应该将字段重新设置为null 我的问题是,这种情况下的最佳实践是什么?我是否应该在每次调用该方法时重置字段 pu

假设我有一个具有一些可变字段的类:

public class Test
{
    private boolean isCorrect;
    private String userId;

    public void run() {...}
    
    // more methods
}
run()
方法将修改这些字段。我的问题是该类的调用方可能多次调用
run()
,因此我应该将字段重新设置为
null

我的问题是,这种情况下的最佳实践是什么?我是否应该在每次调用该方法时重置字段

public void run()
{
    isCorrect = null;
    userId = null;
    // do stuff
}

或者有更干净/更聪明的方法吗?

我会这样做。使用异常。因此,任何胆敢使用
run()
两次的人都会被开除

package test;

import com.sun.jdi.IncompatibleThreadStateException;

public class Test{
    private boolean isRunning = false;
    
    public void run() throws IncompatibleThreadStateException{
        if(this.isRunning) {
            throw new IncompatibleThreadStateException();
        }
        else {
            this.isRunning = true;
        }
    }
    
    public static void main(String[] args) {
        
    }
}

我会这样做的。使用异常。因此,任何胆敢使用
run()
两次的人都会被开除

package test;

import com.sun.jdi.IncompatibleThreadStateException;

public class Test{
    private boolean isRunning = false;
    
    public void run() throws IncompatibleThreadStateException{
        if(this.isRunning) {
            throw new IncompatibleThreadStateException();
        }
        else {
            this.isRunning = true;
        }
    }
    
    public static void main(String[] args) {
        
    }
}

简单的答案是使用局部变量。OP在评论中澄清了
run
在同一实例上调用其他方法,这些方法也希望使用这些变量

这个班应该分开上课。
run
方法应该创建一个包含字段的对象,并调用该字段的方法

public class Test {

    public void run() {
         TestImpl impl = new TestImpl();
         impl.run();
    }
    
    // more methods
}
class TestImpl {
    private boolean isCorrect;
    private String userId;

    public void run() {...}
    
    // more methods
}

您可以将新类设为嵌套类,尽管这确实会导致过度缩进。内部类还可以直接访问
Test
的任何长寿命变量。匿名内部类(或者更隐晦地说,是局部类)更方便,但是缩进。

简单的答案是使用局部变量。OP在评论中澄清了
run
在同一实例上调用其他方法,这些方法也希望使用这些变量

这个班应该分开上课。
run
方法应该创建一个包含字段的对象,并调用该字段的方法

public class Test {

    public void run() {
         TestImpl impl = new TestImpl();
         impl.run();
    }
    
    // more methods
}
class TestImpl {
    private boolean isCorrect;
    private String userId;

    public void run() {...}
    
    // more methods
}


您可以将新类设为嵌套类,尽管这确实会导致过度缩进。内部类还可以直接访问
Test
的任何长寿命变量。匿名内部类(或者更模糊地说,本地类)会更方便,但会缩进。

有没有理由不使用局部变量而不是字段?@TomHawtin-tackline我假设类中的其他方法也依赖于这些值,调用方是否希望调用方多次调用
run()
,或者这仅仅是为了确保没有愚蠢的事情发生?@paladin它不应该被多次调用,但正如你所说的,万一发生愚蠢的事情。如果可能的话,我会尽量避免并发访问该字段,因为它更难正确地实现,而且在很多情况下并不需要。相反,我会尝试为每次运行创建新实例。是否有任何理由不使用局部变量而不是字段?@TomHawtin tackline我假设类中的其他方法也依赖于这些值调用方是否希望调用方多次调用
run()
,或者这仅仅是为了确保没有愚蠢的事情发生?@paladin它不应该被多次调用,但正如你所说的,万一发生愚蠢的事情。如果可能的话,我会尽量避免并发访问该字段,因为它更难正确地实现,而且在很多情况下并不需要。相反,我会尝试为每次运行创建新实例。使用
java.lang.IllegalThreadStateException
也可能是适合您的情况的一种很好的异常类型。我同意:为了防止多个调用,这就是方法。但是您不应该使用
com.sun.jdi.CompatibleThreadstateException
(sun类不是开发的标准),而是使用异常,例如
IllegalStateException
jdi是一个调试接口。你不应该让你的程序依赖于调试API,除非你真的在开发一个调试工具。PS使用
java.lang.IllegalThreadStateException
也可能是适合你情况的一种很好的异常类型。我同意:为了防止多个调用,这是一种方法。但是您不应该使用
com.sun.jdi.CompatibleThreadstateException
(sun类不是开发的标准),而是使用异常,例如
IllegalStateException
jdi是一个调试接口。除非您真正在开发调试工具,否则不应使程序依赖于调试API。使用此方法是有效的,但它能够使创建未定义的程序状态变得更容易。最好使用我的示例中的异常。允许用户以无效的方式使用程序会产生大量开销,最好首先禁止这种行为。不知道这是如何防止OP在每次调用前重置字段的。@paladin OP没有规定方法不能同时执行。这是一个完全独立的问题,最好使用
synchronized
(或者
Semaphore
来防止递归访问,因为Java锁很不幸是重入的)。重复使用变量本身就有风险,通常的建议是尽量减少作用域。@davidxxx为每个调用创建一个新的
TestImpl
,因此生命周期是有限的。@buydadip如果您的“
run()
方法非常大和复杂”然后1)将其拆分为较小的方法,2)为这些方法指定有意义的名称,以描述其用途,而不是“运行”。使用此方法是有效的,但它能够使创建未定义的程序状态变得更容易。最好使用我的示例中的异常。允许用户以无效的方式使用程序会产生大量开销,最好首先禁止这种行为。不知道这是如何防止OP在每次调用前重置字段的。@paladin OP没有规定方法不能同时执行。这是一个完全独立的问题,最好使用
synchronized
(或者
Semaphore
来防止递归访问,因为Java锁很不幸是重入的)。重复使用变量本身就有风险,通常的建议是最小化范围。@davidxxx一个新的
TestImpl<