Java是否支持函数中的静态变量来保持调用之间的值?

Java是否支持函数中的静态变量来保持调用之间的值?,java,Java,我希望在Java中使用此功能,因为我正在设计的函数很少被调用(但当调用时,它会启动一个递归链),因此,我不希望每次实例化类时都将变量作为实例字段来浪费内存 我也不想创建额外的参数,因为我不想用实现细节来增加对函数的外部调用的负担 我尝试了static关键字,但是Java说它是非法的修饰符。有没有直接的替代方案?如果没有,建议采取什么解决方法 我希望它有函数作用域,而不是类作用域。如何在调用之间保持一个值而不“浪费内存”?消耗的内存可以忽略不计 如果需要存储状态,则存储状态:只需使用静态字段 在

我希望在Java中使用此功能,因为我正在设计的函数很少被调用(但当调用时,它会启动一个递归链),因此,我不希望每次实例化类时都将变量作为实例字段来浪费内存

我也不想创建额外的参数,因为我不想用实现细节来增加对函数的外部调用的负担

我尝试了static关键字,但是Java说它是非法的修饰符。有没有直接的替代方案?如果没有,建议采取什么解决方法


我希望它有函数作用域,而不是类作用域。

如何在调用之间保持一个值而不“浪费内存”?消耗的内存可以忽略不计

如果需要存储状态,则存储状态:只需使用静态字段



在多线程应用程序中使用静态变量时,建议谨慎:确保同步对静态字段的访问,以适应从不同线程同时调用的方法。最简单的方法是将
synchronized
关键字添加到
static
方法中,并将该方法作为使用该字段的唯一代码。鉴于该方法很少被调用,这种方法完全可以接受。

如何在调用之间保持一个值而不“浪费内存”?消耗的内存可以忽略不计

如果需要存储状态,则存储状态:只需使用静态字段



在多线程应用程序中使用静态变量时,建议谨慎:确保同步对静态字段的访问,以适应从不同线程同时调用的方法。最简单的方法是将
synchronized
关键字添加到
static
方法中,并将该方法作为使用该字段的唯一代码。考虑到该方法很少被调用,这种方法是完全可以接受的。

静态变量是类级变量。如果您在方法之外定义它,它的行为将完全符合您的要求

请参阅文档:

这个答案的Java代码

public class MyClass {
    static int sa = 10;

    public static void foo() {
        int a = 10;

        a += 5;
        sa += 5;

        System.out.println("a = " + a + " sa = " + sa);
    }

    public static void main(String[] args) {
         for (int i = 0; i < 10; i++) {
             foo();
         }
    } 
}

Output: 
$ java MyClass
a = 15 sa = 15
a = 15 sa = 20
a = 15 sa = 25
a = 15 sa = 30
a = 15 sa = 35
a = 15 sa = 40
a = 15 sa = 45
a = 15 sa = 50
a = 15 sa = 55
a = 15 sa = 60
公共类MyClass{
静态int-sa=10;
公共静态void foo(){
INTA=10;
a+=5;
sa+=5;
System.out.println(“a=“+a+”sa=“+sa”);
}
公共静态void main(字符串[]args){
对于(int i=0;i<10;i++){
foo();
}
} 
}
输出:
$javamyclass
a=15 sa=15
a=15 sa=20
a=15 sa=25
a=15 sa=30
a=15 sa=35
a=15 sa=40
a=15 sa=45
a=15 sa=50
a=15 sa=55
a=15 sa=60

sa在内存中只存在一次,类的所有实例都可以访问它。

静态变量是类级变量。如果您在方法之外定义它,它的行为将完全符合您的要求

请参阅文档:

这个答案的Java代码

public class MyClass {
    static int sa = 10;

    public static void foo() {
        int a = 10;

        a += 5;
        sa += 5;

        System.out.println("a = " + a + " sa = " + sa);
    }

    public static void main(String[] args) {
         for (int i = 0; i < 10; i++) {
             foo();
         }
    } 
}

Output: 
$ java MyClass
a = 15 sa = 15
a = 15 sa = 20
a = 15 sa = 25
a = 15 sa = 30
a = 15 sa = 35
a = 15 sa = 40
a = 15 sa = 45
a = 15 sa = 50
a = 15 sa = 55
a = 15 sa = 60
公共类MyClass{
静态int-sa=10;
公共静态void foo(){
INTA=10;
a+=5;
sa+=5;
System.out.println(“a=“+a+”sa=“+sa”);
}
公共静态void main(字符串[]args){
对于(int i=0;i<10;i++){
foo();
}
} 
}
输出:
$javamyclass
a=15 sa=15
a=15 sa=20
a=15 sa=25
a=15 sa=30
a=15 sa=35
a=15 sa=40
a=15 sa=45
a=15 sa=50
a=15 sa=55
a=15 sa=60

sa在内存中只存在一次,类的所有实例都可以访问它。

我同意波希米亚人的观点,内存不太可能成为问题。另外,重复问题:

为了回应您对向方法添加一个附加参数并公开实现细节的担忧,我想补充一点,有一种方法可以在不公开附加参数的情况下实现这一点。添加一个单独的私有函数,并让公共函数封装递归签名。我在函数式语言中多次看到这一点,但在Java中它当然也是一个选项

你可以做:

public int getResult(int parameter){
    return recursiveImplementation(parameter, <initialState>)
}

private int recursiveImplementation(int parameter, State state){
    //implement recursive logic
}
public int getResult(int参数){
返回递归实现(参数,)
}
私有int递归实现(int参数、状态){
//实现递归逻辑
}

尽管这可能不会解决您对内存的担忧,因为我认为java编译器不会考虑尾部递归优化。

我同意波希米亚的观点,内存不太可能成为问题。另外,重复问题:

为了回应您对向方法添加一个附加参数并公开实现细节的担忧,我想补充一点,有一种方法可以在不公开附加参数的情况下实现这一点。添加一个单独的私有函数,并让公共函数封装递归签名。我在函数式语言中多次看到这一点,但在Java中它当然也是一个选项

你可以做:

public int getResult(int parameter){
    return recursiveImplementation(parameter, <initialState>)
}

private int recursiveImplementation(int parameter, State state){
    //implement recursive logic
}
public int getResult(int参数){
返回递归实现(参数,)
}
私有int递归实现(int参数、状态){
//实现递归逻辑
}

尽管这可能不会解决您对内存的担忧,因为我认为java编译器不会考虑尾部递归优化。

递归调用中在堆栈上设置的变量将是函数(框架)局部变量:


}

递归调用中在堆栈上设置的变量将是函数(帧)本地变量:

}


我希望它有函数作用域,而不是类作用域

那你就不走运了。Java提供了
静态
(类范围)、实例和局部变量。没有Java等价于C的函数作用域
静态
变量


如果变量真的需要是静态的,那么您唯一的选择就是
class myLoader{


    static void foo(){

    int x;

    // do stuff
    }

    }
public void f() { // public API is clean
    fIntern(0); // delegate to private method
}

private void fIntern(int state) {
    ...
    // here, you can preserve state between
    // recursive calls by passing it as argument
    fIntern(state);
    ...
}
static final class FunctionClass {
    private int state1;  // whichever state(s) you want.
    public void call() {
        // do_works...
        // modify state
    }

    public int getState1() {
        return state1;
    }
}

// usage:
FunctionClass functionObject = new FunctionClass();
functionObject.call(); // call1
int state1AfterCall1 = functionObject.getState1();
functionObject.call(); // call2
int state1AfterCall2 = functionObject.getState1();