【问题标题】:How to fix the error "a non-static method can't be referenced from a static context"? [duplicate]如何修复“无法从静态上下文引用非静态方法”的错误? [复制]
【发布时间】:2013-12-27 10:56:14
【问题描述】:

我正在尝试使用递归方法计算某个整数(从 0 到 21)的阶乘。我在主类之外创建了一个单独的方法。但是在 main 方法中打印阶乘时,它会显示错误。如何解决?

package looping;

import java.io.PrintStream;

public class Looping {
    public long fact(long num)
    {
        if(num<=1)
        return 1;
        else
            return num*fact(num-1);
    }
    public static void main(String[] args) {

        for(int i=0;i<=21;i++){
         System.out.printf("%d!=d\n",i,fact(i));
        }

    }
}

【问题讨论】:

  • 这是我学习 java 时难以掌握的事情之一。

标签: java


【解决方案1】:

如果不创建 Looping 类的对象,就不能调用 fact() 方法。

public static void main(String[] args) {
    Looping loop=new Looping()
    for(int i=0;i<=21;i++){
     System.out.printf("%d!=%d\n",i,loop.fact(i));
    }

}

或者另一种方式是创建 fact() 作为类的静态方法。

public static long fact(long num)
{
    if(num<=1)
        return 1;
    else
        return num*fact(num-1);
}

【讨论】:

  • 虽然它是同一个类,但它是必需的对象吗?
  • 因为该类的对象尚未创建。对于访问静态方法,我们不需要任何对象。
  • Ronak,错误消失了,但它不计算阶乘。
  • 您缺少第二个“d”的 %....System.out.printf("%d!=%d\n",i,loop.fact(i));跨度>
  • 如果它适合你,那么选择正确答案...
【解决方案2】:

静态方法只调用静态方法 所以只需声明你的方法静态

public static long fact(long num){

}

【讨论】:

    【解决方案3】:

    您可以做两件事。

    要么

    (1) 您可以将fact 设为静态方法,方法是在其声明中将static 放在public 之后。

    或者

    (2) 您可以创建Looping 类的对象,并使用它来运行对fact 的调用,如下所示。

    public static void main(String[] args) {
    
        Looping looping = new Looping();
        for(int i=0;i<=21;i++){
         System.out.printf("%d!=%d\n", i, looping.fact(i));
        }
    }
    

    您选择哪个没有任何区别,因为Looping 类的对象没有任何字段,这意味着它不携带任何数据。你是否制作这样的对象并不重要;除了要使用非静态方法,还需要一个对象。

    如果对象有一些字段,那么非静态方法就是可以引用这些字段的方法。但是由于没有字段,因此方法是否是静态的没有区别。因此,我可能会在这里选择选项 (1) - 只需将方法设为静态即可。

    但是,如果将来我想对 Looping 类进行变体 - 即子类,每个子类对 fact 方法的实现略有不同;那么我真的需要选择选项(2)。在子类中,您不能真正拥有不同版本的静态方法。当你编写一个类时,你真的不知道将来是否需要它的一些子类,它们的行为略有不同。这些可能是要在您的程序中使用的子类,也可能是您用于测试的模拟子类之类的东西。

    因此,当然,避免使用静态方法总是值得的。任何类都需要拥有的唯一静态方法是main 方法。随着程序的增长和越来越多的类,任何其他静态方法都可能给您带来问题。静态方法会使测试更加困难。它们肯定会使多态性的实现变得更加困难。

    我意识到这个论点可能超出了您当前的 Java 知识范围。但值得了解选项 (2) 中发生了什么,并养成使用它的习惯,而不是让所有方法默认为静态。

    【讨论】:

    • 也许你可以说——“(1) 你可以把 fact 变成一个静态方法,通过在声明的 public 后面加上 static 这个词。” (由于效率原因不建议)“:P.. BTW +1 用于带出这两种方法..
    • 为什么我会说“由于效率原因不建议”?我绝对建议选项(1)。
    • 我认为创建一个对象来访问方法总是比使方法静态并通过类访问它更好......好吧,我的道歉......这只是“我”的想法。 ..
    • @TheLostMind 嗯,你是对的,但原因比你说的要微妙一些。我根据您的 cmets 扩展了我的答案。
    【解决方案4】:

    /在main里面/

    Looping looping = new Looping();
    for(int i=0;i<=21;i++){
        System.out.printf("%d!=d\n",i,looping.fact(i));
    }
    

    【讨论】:

      【解决方案5】:

      static 表示“不需要在使用new 创建的对象中”

      static 表示您需要在这样的对象内。 this 必须可用。

      【讨论】:

      • 为什么我的输出是这样的? 0!=d 1!=d 2!=d 3!=d 4!=d 5!=d 6!=d 7!=d 8!=d 9!=d 10!=d 11!=d 12! =d 13!=d 14!=d 15!=d 16!=d 17!=d 18!=d 19!=d 20!=d 21!=d 不计算阶乘
      • 您缺少第二个“d”的 %....System.out.printf("%d!=%d\n",i,loop.fact(i));跨度>
      【解决方案6】:

      你好像忘了创建类的对象

        Looping loop=new Looping();
          for(int i=0;i<=21;i++){
           System.out.printf("%d!=d\n",i,loop.fact(i));
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-19
        • 1970-01-01
        • 1970-01-01
        • 2015-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多