代码之家  ›  专栏  ›  技术社区  ›  tgeros

Java字符串参数

  •  2
  • tgeros  · 技术社区  · 17 年前

    我来自.net背景,想知道创建一个返回布尔值并修改通过参数传递的字符串的方法的公认方式。我知道字符串在Java中是不可变的,所以下面的代码段总是会产生一个空字符串。我只能返回布尔值。不能抛出异常。如果我需要将String类包装在StringHolder中,我可以在哪个包中找到它。

    public static void DoStuff()
    {
        String msg = "";
        if (GetMessage(msg))
        {
           System.out.println(msg);
        }
    }
    
    11 回复  |  直到 17 年前
        1
  •  9
  •   Michael Borgwardt    17 年前

    使用java.lang.StringBuilder-基本上是一个可变的字符串。但是,返回修改后的字符串会更安全,也更“java风格”。

        2
  •  6
  •   Tom Hawtin - tackline    11 年前

    我强烈建议您不要使用StringBuilder、holder或类似工具。他们是黑客。你想使用字符串,而不是构建器。

    最明显的方法是返回一个包含要返回的数据的对象。David的[bombe.livejournal.com的]解决方案涵盖了这一点,所以我不会重复。但是,我建议,与其试图使其成为通用的数据球,不如使其具体化。把它变成一个物体,也许它甚至可以培养出真正的行为。(如果你真的想去城里,隐藏构造函数,给它一个静态的创建方法。)

    第二种方法在Java中不太受支持,是反转调用。不要返回结果,而是告诉回调函数结果。

    (更重要的)使用代码如下(它看起来有点奇怪,因为它既不具体,也不通用):

    String userMessage = thing.doStuff(new StuffHandler<String>() {
        public String stuff(boolean success, String message) {
            return message+" was "+(success ? "succesful" : "unsuccesful");
        }
    });
    

    实现过程大致如下:

    public interface StuffHandler<T> {
        T stuff(boolean success, String message);
    }
    
    [...]
    
        public <T> T doStuff(StuffHandler<T> handler) {
            handler.stuff(isSuccess(), getMessage());
        }
    

    第三种方法是简单地将该方法一分为二。这可能可行,也可能不可行。

        3
  •  5
  •   Bombe    17 年前

    首先,我可能没有这些要求。我相信他们可以变通。如果你不想这样做,我建议为你的两个结果返回一个容器对象:

    public class ResultContainer {
        private final boolean success;
        private final String result;
        public ResultContainer(boolean success, String result) {
            this.success = success;
            this.result = result;
        }
        public boolean isSuccess() { return success; }
        public String getResult() { return result; }
    }
    

    在你的主代码中:

    ResultContainer resultContainer = GetMessage(message);
    if (resultContainer.isSuccess()) {
        System.out.println(resultContainer.getResult());
    }
    

    GetMessage() 显然会创建一个新的实例 ResultContainer 并返回它,填充返回值。

    (使用泛型 结果容器 留给读者作为练习。)

        4
  •  3
  •   J. A. Faucett    17 年前

    通过使用泛型,一个更优雅的holder类可以重用于任何类型的对象:

    public class Holder<T> {
      T item;
      public Holder( T item) { set( item);}
      public T get( ) { return item;}
      public void set( T item) { this.item = item;}
    }
    

    DoStuff( ) 然后看起来像:

    public static void DoStuff( ) {
      String msg = "";
      Holder<String> holder = new Holder<String>( msg);
      if ( getMessage( holder)) { System.out.println( holder.get( ));}
    }
    

    GetMessage( ) 必须打电话 holder.set( a_string) .

        5
  •  2
  •   Pete Kirkham    17 年前

    Java是一种基于类的面向对象语言,因此它的习惯用法倾向于创建类来封装数据及其周围的行为。

    你有一个数据(消息),它是以某种方式获得的,然后如果满足某些条件,就会用它做其他事情。在外部控制对象中将这种行为变成一系列get、ifs和其他操作通常表明程序员还不理解OOP。

    我只能返回布尔值。不能抛出异常。

    我可以建议你应该使用Fortran或C而不是Java吗?过程语言通常有变异和返回标志的习惯用法,这非常适合这种范式(在没有自动内存管理的情况下,调用者创建并传递一个填充的缓冲区;这允许调用者在处理完缓冲区时安全地释放缓冲区;Java不需要这样做,所以如果你看看Map.get(),它会在失败时返回String或null——不需要管理调用者中的内存)。至少,不要费心在惯用的Java中找到可接受的方法——有了这些约束,就不会了,不管是谁强迫你这样做,都是一个糟糕的选择,这意味着你要么有黑客,要么最终会得到冗长的代码,试图做出一个不黑客的解决方案。

        6
  •  1
  •   JamesSugrue    17 年前

    不能将字符串用作输出参数。这样做的方法是使用StringBuilder类,或者在失败时返回null。

    Discussion Here

        7
  •  1
  •   Paul Tomblin    17 年前

    字符串是不可变的,所以是的,您需要将字符串包装在StringHolder中。你可以写自己的,就像

      class StringHolder
      {
         String msg;
      }
    
      StringHolder sMsg = new StringHolder();
      sMsg.msg = "";
      if (GetMessage(sMsg))
      {
         System.out.println(sMsg.msg);
      }
    
        8
  •  1
  •   Stobor    17 年前

    一个微不足道的StringHolder将是一个String[1]。

    
    bool GetMessage(String[] output)
    {
         if(output.length < 1)
              throw new Exception("Output must be a String[1]");
         output[0] = "You win!";
    }
    
    public static void DoStuff()
    {
          String[] msg = new String[1];
          if(GetMessage(msg))
          {
              System.out.println(msg[0]);
          }
    }
    

    不过,StringBuilder可能是实现这一点的规范方法。

        9
  •  1
  •   OscarRyz    17 年前

    这是一个奇怪的要求。

    为什么不用正确的方式(或者至少用java的方式)呢?这就像试图从一个函数中得到两个结果。比如减法(2,2)返回0和“早上好,先生”。

    不管怎样,你可以试试这两个选项。

    第一。 字符串拼接 这不是最好的使用方法,因为你不是在“构建”一个字符串。

    public static void doStuff(){
        String msg = "";
        StringBuilder sb = new StringBuilder();
        if ( getMessage( sb ) ) {
            System.out.println( sb );
        }
    }
    
    public static boolean getMessage( StringBuilder sb ) {
        if ( "".equals( sb.toString() )) {
            sb.delete( 0, sb.length() );
            sb.append("It was empty");
            return true;
        } else {
            return false;
        }
    }
    

    第二 线夹 (就这点而言,任何东西都可以)也不要太java风格,但要做这项工作。这将是我认识的大多数java开发人员使用的。

    public static void doStuff(){
        String msg = "";
        String [] holder = { msg };
        if ( getMessage( holder ) ){
            System.out.println( holder[0]  );
        }
    }
    public static boolean getMessage( String [] holder ) {
        if ( "".equals(  holder[0] )) {
            holder[0] = "It was empty";
            return true;
        } else {
            return false;
        }
    }
    

    第三。选项。不是你问的,而是我会怎么做。不幸的是,违反了“返回布尔值”的条件。

    public void doStuff() { 
        String msg = "";
        String result = getMessage( msg );
        if ( result != msg ) {
            System.out.println( result );
        }
    }
    public static String getMessage( String msg ) {
        if ( "".equals(msg){
            return "It was empty";
        }
        return msg
    }
    

    选择一个。

    笔记

    虽然不是每个人都喜欢这样(Jon Skeet会说“不是普遍接受的”),但请看看我使用的java编码风格(同一行中以小写和大括号开头的方法)。有时候,尊重你正在编码的平台很重要。至少我用C#编码时就是这么做的(很少顺便说一句)

        10
  •  0
  •   Matt    17 年前

    public boolean doStuff(String msg) { boolean boolTest = false; msg += "Appending something to msg"; int msgLength = msg.length(); if ( msgLength > 80 ) { boolTest = true; return boolTest; } return boolTest; }

    这就是你要找的吗?我假设布尔测试类似于测试更改的消息是否太长而无法显示(大于80长度)或类似的东西,并且您不需要调用另一个方法来更改doStuff()中的消息字符串。

    不过,这里可能完全跑偏了。 :-)

        11
  •  0
  •   Venu    17 年前

    首先,你编写程序,并用这样的代码制作它们:

    Process p = Runtime.exec("java GetMessage.class " + String);
    

    给你的提示:Runtime.exec应该在任何地方都使用。然后你可以制作许多程序。

    然后你等待返回这样的状态码:

    if (p.returnCode() = 1) 
      Out.printWord("1 made back"):
    else 
      {
      Out.printWord("B Made back");
      }
    

    这样你就可以像在这个程序之外一样使用这个程序了。使代码可重新悬浮是件好事。相信我,我已经干了很多年了。专业人士就是这样编写代码的。