Java 字符串参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/342638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:01:34  来源:igfitidea点击:

Java String Parameters

javaparametersstringidioms

提问by tgeros

I'm coming from a .net background and want to know the accepted way of creating a method that returns a boolean and modifies a string that was passed in via parameter. I understand Strings are immutable in Java so the below snippet will always produce an empty string. I am constrained to return boolean only. Exceptions can't be thrown. If I need to wrap the String class in, say, a StringHolder, what package could I find this in.

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

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

回答by Michael Borgwardt

Use a java.lang.StringBuilder - basically a mutable String. However, it would be safer and more "Java style" to return the modified String.

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

回答by Tom Hawtin - tackline

I strongly suggest you do not use StringBuilder, holder or similar. They are hacks. You want to be working with Strings, not builders.

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

The most obvious approach is to return an object containing the data you want to return. David's [bombe.livejournal.com's] solution covers that, so I won't repeat it. However, I would suggest instead of trying to make it generic ball of data, make it specific. Make it like an object, perhaps it could even grow real behaviour. (And if you really want to go to town, hide the constructor and give it a static creation method instead.)

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

A second approach, not so well supported in Java, is to invert the calls. Instead of returning a result, tell a callback the result.

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

The (more important) usage code would be something like (it looks a bit odd because it isn't specific, nor is it generic):

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

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

The implementation goes something like:

实现是这样的:

public interface StuffHandler<T> {
    T stuff(boolean success, String message);
}

[...]

    public <T> T doStuff(StuffHandler<T> handler) {
        handler.stuff(isSuccess(), getMessage());
    }

A third approach is simply to break the method in two. That may or may not be feasible.

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

回答by Bombe

First off I probably wouldn't have these requirements. I'm sure they can be worked around. If you don't want to do that, I'd recommend returning a container object for your two results:

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

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

And in your main code:

在你的主要代码中:

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

GetMessage()would obviously create a new instance of a ResultContainerand return it, filled with the return values.

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

(Using Generics for the ResultContaineris left as an exercise for the reader.)

(使用泛型ResultContainer作为读者的练习。)

回答by J. A. Faucett

A more elegant holder class could be reused for any type of object by utilizing generics:

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

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( )would then look like:

DoStuff( )然后看起来像:

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

and GetMessage( )would have to call holder.set( a_string).

并且GetMessage( )不得不打电话holder.set( a_string)

回答by Pete Kirkham

Java's a class-based object oriented language, so its idioms tend to create classes to encapsulate data with the behaviour that surrounds it.

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

You have a datum - the message - which is obtained in some manner, then if some condition is met, something else is done with it. Making that behaviour a sequence of gets, ifs and other operations in an external controlling object is often a sign that the programmer hasn't understood OOP.

你有一个数据——消息——以某种方式获得,然后如果满足某个条件,就会用它来做其他事情。使该行为成为外部控制对象中的 get、if 和其他操作序列通常表明程序员尚未理解 OOP。

I am constrained to return boolean only. Exceptions can't be thrown.

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

May I suggest you should be using Fortran or C rather than Java? Procedural languages often have the idiom of mutation and returning a flag, which is well suited to that paradigm (in the absence of automatic memory management, the caller creates and passes in a buffer which is populated; this allows the buffer to be freed safely when the caller is done with it; Java doesn't need to do that, so if you look at say Map.get() it returns a String or null if it fails - no need to manage the memory in the caller). At least, don't bother trying to find the accepted way of doing it in idiomatic Java - with those constraints, it won't be, and whoever is forcing them on you has made a bad choice, which will mean you either have hacks, or end up with verbose code trying to make a non-hacky solution.

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

回答by JamesSugrue

You can't use a string as an output parameter. The way to do it would be to use a StringBuilder class instead or return null for a failure.

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

Discussion Here

在这里讨论

回答by Paul Tomblin

Strings are immutable, so yes, you will need to wrap the String in a StringHolder. You can write your own as simply as

字符串是不可变的,所以是的,您需要将字符串包装在 StringHolder 中。你可以像这样简单地编写自己的

  class StringHolder
  {
     String msg;
  }

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

回答by Stobor

A trivial StringHolder would be a String[1].

一个普通的 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 is probably the canonical way to do it, though.

不过,StringBuilder 可能是规范的做法。

回答by OscarRyz

That is some strange requirement.

这是一些奇怪的要求。

Why don't do it the right way ( or at least the java way ) ? Is like trying to get two results from a function. Like subtract( 2 , 2 ) returns 0 and "Good morning sir".

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

Well anyway, you can try these two options.

好吧,你可以试试这两个选项。

1st. StringBuilderNot the best thing to use, since you're not "building" an String.

第一。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;
    }
}

2nd StringHolder( anything holder for that matter ) Not too java style either but do the work. This would be the one used by most java developer I know.

第二个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;
    }
}

3rd. Option. not what you asked but what I would do. Unfortunately violates the "return boolean" condition.

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

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
}

Choose one.

选一个。

Note

笔记

Although not everyone likes this ( Jon Skeet would say "Is not universally accepted" ) , please take a look at the java coding style I'm using ( methods starting with lower case and braces in the same line ). Sometimes it is important to respect the platform you're coding in. At least that's what I do when I code in C# ( very seldom btw )

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

回答by OscarRyz

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

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

Is this kind of what you're looking for? I'm assuming the boolean test is something like testing if the changed message is too long for a display (greater than 80 length) or something similar, and that you don't need to call another method to change the message string inside of doStuff().

这是您正在寻找的类型吗?我假设布尔测试类似于测试更改的消息对于显示来说是否太长(长度大于 80)或类似的东西,并且您不需要调用另一种方法来更改 doStuff 中的消息字符串().

Could be completely off-base here, though. :-)

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