【问题标题】:Can I change String object's value passed to my method?我可以更改传递给我的方法的字符串对象的值吗?
【发布时间】:2012-01-03 03:58:31
【问题描述】:

我发现了以下问题Is Java "pass-by-reference" or "pass-by-value"?

我几乎阅读了所有内容,但还没有找到如果我想要foo(-) 方法来更改我的String,该怎么办? (也许也没有参考,这对我来说并不重要)。

void foo(String errorText){ 
    errorText="bla bla";
}

int main(){ 
    String error="initial"; 
    foo(error); 
    System.out.println(error);
}

我想在控制台上看到bla bla。有可能吗?

【问题讨论】:

    标签: java string parameters pass-by-reference immutability


    【解决方案1】:

    您不能更改fooerrorText 的值,因为该方法当前已声明。即使您将字符串 errorText 的引用传递给 foo,Java Strings 也是不可变的——您无法更改它们。

    但是,您可以使用StringBuffer(或StringBuilder)。这些类可以在您的foo 方法中进行编辑。

    public class Test {
        public static void foo(StringBuilder errorText){ 
            errorText.delete(0, errorText.length());
            errorText.append("bla bla");
        }
    
        public static void main(String[] args) { 
            StringBuilder error=new StringBuilder("initial");
            foo(error); 
            System.out.println(error);
        }
    }
    

    其他解决方案是使用包装类(创建一个类来保存您的字符串引用,并更改 foo 中的引用),或者只返回字符串。

    【讨论】:

      【解决方案2】:

      字符串值是不可变的——所以一旦你得到一个值,你就会被它困住。

      【讨论】:

        【解决方案3】:

        文字Strings被Java语言特殊处理;您的代码大致相当于:

        void foo(String errorText){ // at this point, errorText refers to the original string
            errorText=new String("bla bla"); // now it refers to a new string
        }
        
        int main(){ 
            String error=new String("initial"); // error is a reference to the original string
            foo(error); // pass a *copy* of the reference
            System.out.println(error);
        }
        

        换句话说,您只是将本地引用 errorText 指向不同的 String 对象,这不会影响方法之外的任何内容。

        不过,更一般地说,Strings 是不可变的;没有办法修改它们。

        【讨论】:

          【解决方案4】:

          您可以重新分配字符串引用:

          String foo(String err) {
            return "bla blah"
          }
          
          error = foo(error);
          

          【讨论】:

            【解决方案5】:

            要么使用方法的返回值,要么创建一个包装类。

            让它返回值:

            String foo(String errorText){ 
                return "bla bla";
            }
            
            int main(){ 
                String error="initial"; 
                error = foo(error); 
                System.out.println(error);
            }
            

            将值包装在一个对象中:

            class StringWrapper {
                private String string;
                public StringWrapper(String s) {
                    this.string = s;
                }
                public String getString() {
                    return this.string;
                }
                public void setString(String s) {
                    this.string = s;
                }
            }
            
            void foo(StringWrapper errorText){ 
                errorText.setString("bla bla");
            }
            
            int main(){ 
                StringWrapper error=new StringWrapper("initial"); 
                foo(error); 
                System.out.println(error.getString());
            }
            

            【讨论】:

              【解决方案6】:

              是的,您可以借助反射来更改此设置,但这是违反规则的。

              void foo(String errorText) {
                  try {
                      final Class<String> type = String.class;
                      final java.lang.reflect.Field valueField = type.getDeclaredField("value");
                      valueField.setAccessible(true);
                      valueField.set(errorText, "bla bla".toCharArray());
                  } catch (Exception e) {
                  }
              
              }
              
              public static void main(String[] args) {
                  String error = new String("initial");
                  foo(error);
                  System.out.println(error);
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-10-09
                • 2017-12-08
                • 2020-09-25
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多