【问题标题】:Java String ParametersJava 字符串参数
【发布时间】:2010-09-25 10:51:02
【问题描述】:

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

public static void DoStuff()
{
    String msg = "";
    if (GetMessage(msg))
    {
       System.out.println(msg);
    }
}

【问题讨论】:

  • 我喜欢这个问题的地方是“我只能返回布尔值。不能抛出异常。”他们是否还会告诉您所有 for 循环都必须作为 while 循环来完成?如果不允许使用 Java,为什么还要使用 Java。祝你好运。
  • 你能澄清一下你需要什么吗?您写“我被限制返回布尔值”,但您的方法声明为“public static void DoStuff()”
  • @joe_mucchuiello 这是一个拒绝使用异常或任何现代语言习语的单一开发人员。 @Bevan 这是需要返回布尔值的 GetMessage 方法。没有那么多DoStuff。为混乱道歉。

标签: java parameters string idioms


【解决方案1】:

我强烈建议你不要使用 StringBuilder、holder 或类似的东西。他们是黑客。您希望使用字符串,而不是构建器。

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

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());
    }

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

【讨论】:

  • 感谢汤姆付出的努力。 StringBuilder 为我工作,尽管正如你所说,它是一个 hack。我现在需要最简单、最容易理解的解决方案。
【解决方案2】:

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

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");
  }

这样你就可以在这个程序之外使用其他程序。使代码可重用是件好事。把它从我这里拿走,我已经参与了很多年。这就是专业人士编写代码的方式。

【讨论】:

    【解决方案3】:

    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 内部的消息字符串()。

    不过,这里可能完全脱离基地。 :-)

    【讨论】:

      【解决方案4】:

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

      您有一个数据 - 消息 - 以某种方式获得,然后如果满足某些条件,则对其进行其他操作。在外部控制对象中使该行为成为一系列获取、ifs 和其他操作通常表明程序员还没有理解 OOP。

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

      我可以建议您使用 Fortran 或 C 而不是 Java 吗?过程语言通常具有突变和返回标志的习惯用法,这非常适合该范例(在没有自动内存管理的情况下,调用者创建并传入一个填充的缓冲区;这允许缓冲区在以下情况下安全释放调用者完成了它;Java 不需要这样做,所以如果你查看说 Map.get() 它返回一个字符串,如果失败则返回 null - 无需管理调用者中的内存)。至少,不要费心试图在惯用的 Java 中找到公认的方法——有了这些限制,它就不会了,而且强迫他们的人做出了错误的选择,这意味着你要么有黑客,或者以试图制作非hacky解决方案的冗长代码结束。

      【讨论】:

        【解决方案5】:

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

        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 的新实例并返回它,并用返回值填充。

        (将泛型用于ResultContainer留给读者作为练习。)

        【讨论】:

          【解决方案6】:

          通过使用泛型,可以为任何类型的对象重用更优雅的持有者类:

          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)

          【讨论】:

            【解决方案7】:

            这是一个奇怪的要求。

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

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

            第一。 StringBuilder 不是最好用的东西,因为你不是在“构建”一个字符串。

            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;
                }
            }
            

            第二个 StringHolder (任何持有者)也不是太 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# 中编码时就是这样做的(顺便说一句很少)

            【讨论】:

            • 如果(结果!= msg)?啧啧啧!
            • 我从未声称 命名 约定并没有被普遍接受。只有支撑样式。那是因为 Sun 如何支持他们的代码并不重要——我的代码和他们的代码之间的不一致不会出现在我的代码中。命名确实如此,因为我在我的代码中使用了 Sun 的类。
            【解决方案8】:

            一个普通的 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】:

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

                class StringHolder
                {
                   String msg;
                }
              
                StringHolder sMsg = new StringHolder();
                sMsg.msg = "";
                if (GetMessage(sMsg))
                {
                   System.out.println(sMsg.msg);
                }
              

              【讨论】:

                【解决方案10】:

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

                Discussion Here

                【讨论】:

                  【解决方案11】:

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

                  【讨论】:

                    猜你喜欢
                    • 2013-03-29
                    • 1970-01-01
                    • 2012-02-21
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-11-04
                    • 1970-01-01
                    相关资源
                    最近更新 更多