【问题标题】:Calling non static method in static method [duplicate]在静态方法中调用非静态方法[重复]
【发布时间】:2018-09-15 20:17:55
【问题描述】:

我的代码有点问题。我试图找到运行时来与我为这个问题准备的一些数学进行比较。我有一个特别是我正在测试的方法是这样的:

 public static int foo(int n, int k){
        long startTime = System.nanoTime();
        if(n<=k){
            long endTime = System.nanoTime();
            System.out.println("checkFoo");
            System.out.println("start time: " +startTime);
            System.out.println("end time: " +endTime);
            return 1;
        }
        else{
            return foo(n/k,k) + 1;
        }
    }

我通过以下方式在我的 main 方法中测试此代码:

public static void main(String[] args){
    foo(1, 1);
    foo(5, 1); 
    foo(10, 1);
    foo(100, 1);
}

我收到一个错误提示

Exception in thread "main" java.lang.StackOverflowError

然后它重复该行:

at Problem3.foo(Problem3.java:42) 

我想知道这是否与 foo 应该返回一个 int 的事实有关,也许我只是没有正确调用该函数。如果是这种情况,调用此函数的正确方法是什么,以便它也打印出我需要的信息?还是这个错误与我理解的完全不同?

【问题讨论】:

  • 对于foo(5,1),你有n=5,k=1,所以n&lt;=k 是假的,foo(n/k,k) 表示foo(5/1,1) 又名foo(5,1),所以用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后用相同的参数调用自己,然后堆栈溢出
  • @Andreas 感谢您了解这一点。我正在以完全不同的方式阅读代码。

标签: java exception runtime static-methods


【解决方案1】:

你只是有一个无限递归循环:

foo(5, 1): n = 5, k = 1
calls foo(5 / 1, 1), i.e. foo(5, 1)
calls foo(5 / 1, 1), i.e. foo(5, 1)
calls foo(5 / 1, 1), i.e. foo(5, 1)
...

【讨论】:

    【解决方案2】:

    如果问题是错误的返回类型,你会得到一个编译错误。当方法用完所有已分配的内存时,会导致 stackoverflow 错误。有关如何导致 stackoverflow 错误的更多信息,请阅读以下内容:What is a StackOverflowError?

    【讨论】:

      【解决方案3】:

      好像你有一个无限循环的函数调用,这会导致 JVM 的堆溢出。尝试包含一些输入验证以防止出现此类情况。

      【讨论】:

        【解决方案4】:

        您的代码在无限循环中运行,但您可以像下面这样捕获它

        public static int foo(int n, int k){
                long startTime = System.nanoTime();
                if(n<=k){`enter code here`
                    long endTime = System.nanoTime();
                    System.out.println("checkFoo");
                    System.out.println("start time: " +startTime);
                    System.out.println("end time: " +endTime);
                    return 1;
                }
                else{
                    try {
                        return foo(n/k,k) + 1;
                    } catch (StackOverflowError e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        return 1;
                    }
                }
            }
        

        【讨论】:

          【解决方案5】:

          当您调用此foo(5, 1); 时,参数为51,这意味着foo if(5&lt;=1) 内部的逻辑失败,因此else 中的代码将执行,即return foo(5/1,1) + 1; 这将调用@ 987654328@ 一次又一次,重复,再重复……导致StackOverflowError

          foo(5, 1); 总是调用不结束 foo,所以你得到StackOverflowError 尝试结束此通话

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-03
            • 1970-01-01
            • 2023-03-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多