【问题标题】:Java String function can not be called because it's not staticJava String 函数不能被调用,因为它不是静态的
【发布时间】:2014-03-22 23:05:48
【问题描述】:

让我进一步解释。我有一个返回反转字符串的字符串函数(称为 stringReversal),它在函数中没有错误。但是,当我尝试使用主函数中的System.out.println() 进行打印时,它给了我错误“无法从 StringReverse 类型对非静态方法 stringReversal (string s) 进行静态引用”。

我尝试给我的 stringReversal 一个 static 修饰符,但这样做之后,它给了我运行时错误。

我的代码如下所示:

public class StringReverse {

    public String stringReversal(String s){

        if(s == null){
            return null;
        }

        else if(s.length()% 2 == 0){
            int size = s.length();

            for(int i =0; i<s.length(); i++){
                s.replace(s.charAt(i), s.charAt(size));
                size--;
                if(i == (s.length()/2) || size==0)
                    break;
            }
        }

        else{
            for(int i =0; i<s.length(); i++){
                int size = s.length();

                s.replace(s.charAt(i), s.charAt(size));
                size--;

                if(i == ((s.length()/2) +1) || size==0 )
                    break;
            }
        }

        return s;
    }

    public static void main(String[] args) {
        String str = "Hello";
        String rev = stringReversal(str);

        System.out.println();
    }

}

【问题讨论】:

  • 你遇到了什么运行时错误?
  • @VinceEmigh 它无法编译。 OP 发布了他/她的错误。
  • 我仍然不赞成。 @Ebad 您是否在 发布到 StackOverflow 之前搜索了您的错误消息并遵循了您得到的任何建议?
  • 让我猜猜 -- 在将方法设为静态后,您会收到此运行时错误:Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind ex out of range: 5 at java.lang.String.charAt(Unknown Source) at StringReverse.stringReversal(StringReverse.java:24) at StringReverse.main(StringReverse.java:37) ---- 您知道,要做的事情是实际报告该错误是什么,而不是说“我遇到了错误”。
  • 基本上,您的问题是:int size = s.length(); s.replace(s.charAt(i), s.charAt(size));。这里的“size”将是s 的长度,charAt 必须传递一个介于 0 和 size-1 之间的参数。所以难免会报错。 (当然,很容易判断错误是什么,因为上面的异常消息为您提供了方法(charAt)以及调用它的位置(stringReversal,第 24 行)。

标签: java string methods static-methods


【解决方案1】:

你必须实例化你的类来调用对象成员,或者你需要让你的函数静态,表明它不是面向对象范式的一部分

你可以这样做

StringReverse sr = new StringReverse();
String rev = sr.stringReversal("hello");

或以不同的方式声明您的方法

public static String stringReversal(String s)

其实StringReverse这个类名本身听起来不像是某种对象,所以第二种方式是首选impo

您遇到的更深层次的问题是对 Java 如何处理 OO 和一般入口函数的困惑。 Java 主要是一种 OO 语言,所以大多数时候一切都是对象或对象的成员。但是当你告诉 VM 运行一些 java 代码时,必须有一个开始的地方,这是 main 方法。必须有一个主要方法,它必须在某个类下,但它与包含它的类实际上无关。在 main 方法中,您可以通过实例化对象并调用其成员(方法 1)来开始您的 OO 生活,或者通过将其他静态成员调用为过程(方法 2)在意大利面条世界中停留更长时间。

【讨论】:

    【解决方案2】:

    你有两个选择:

    1. 保持方法非static,然后创建您的类的实例来调用该方法:

      public static void main(String[] args) {
          String str = "Hello";
      
          StringReverse sr = new StringReverse(); // instance of class
          String rev = sr.stringReversal(str);
      
          System.out.println(); // just prints a blank line lol...
      }
      
    2. 制作方法static(你应该这样做):

      public static String stringReversal(String s) {
          // ...
      }
      
      public static void main(String[] args) {
          String str = "Hello";
          String rev = stringReversal(str);
      
          System.out.println(); // just prints a blank line lol...
      }
      

    无论哪种方式,您都必须修复“运行时错误”。你无法解决这个问题。如果你的方法不起作用,保持它不是 static 也不会使它起作用。

    顺便说一句,我认为你的意思是 System.out.println(rev); 而不是 System.out.println();


    为了记录,这里是如何轻松地反转字符串(两种方法都有效):

    public static String stringReversal(String s) {
    
        StringBuffer reverseString = new StringBuffer();
    
        // reverse the string
        for (int i = s.length() - 1; i > -1; i--) {
            reverseString.append(s.charAt(i));
        }
    
        return reverseString.toString();
    }
    
    /* using the reverse() method in the StringBuffer class
       instead of reversing the string through iterations */
    public static String stringReversal2(String s) {
        return new StringBuffer(s).reverse().toString();
    }
    

    【讨论】:

      【解决方案3】:

      发生这种情况是因为您的 Main 方法是静态的,但它所在的类不是。为了调用非静态方法,您需要创建该类的实例。或者,该方法可以设为静态,但为了引用它,您需要在调用中包含类名(就像使用类本身一样包含该方法的对象 - 见下文)。

      这个问题有三种解决方案:

      • 创建一个类的实例并从您的对象调用方法(推荐)
      • 将方法设为静态并使用 StringReverse.stringReversal()。
      • 将类和方法设为静态。

      【讨论】:

      • @dognose 是的。请解释一下。
      • @djechlin static Main 方法是约定的。但是你不会把你的整个应用程序变成“静态调用”,只是因为你的主要方法是静态的。听说过应用程序实例吗?
      • @dognose 你是对的,因为 main 是静态的并不意味着方法应该是。但这无论如何都应该是静态的。如果我将它作为包的一部分编写,我肯定会将其设为静态,因为它不需要内部状态来工作,也不应该需要内存或代码行来创建对象。事实上Apache's StringUtils.reverse 是静态的。
      • @dognose 作为一个非常广泛的经验法则,但有许多例外,我想说方法应该是静态的,如果可以的话。但是,如果 OP 在变量上而不是在方法上遇到这个问题,那么那些确实应该是实例变量并且 main 应该实例化一个对象的可能性是一样的。无论如何,我猜这远远超出了 OP 的考虑范围......并且只使用静态是 Java 入门书籍第 3 章的正确做法。
      • 这个方法绝对没有理由不是静态的,因为它在包含的类中没有引用任何内容。
      猜你喜欢
      • 2021-11-12
      • 2021-05-31
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多