我来自.net背景,想知道创建一个方法的可接受方式,该方法返回一个布尔值并修改一个通过参数传入的字符串。我理解字符串在Java中是不可变的,因此下面的代码片段将始终产生一个空字符串。我被限制只返回布尔值。不能抛出例外情况。如果我需要将String类包装在一个StringHolder中,我可以在哪个包中找到它。
public static void DoStuff()
{
String msg = "";
if (GetMessage(msg))
{
System.out.println(msg);
}
}
答案 0 :(得分:9)
使用java.lang.StringBuilder - 基本上是一个可变的String。但是,返回修改后的String会更安全,更“Java样式”。
答案 1 :(得分:6)
我强烈建议您不要使用StringBuilder,持有者或类似的东西。他们是黑客。你想与Strings合作,而不是建设者。
最明显的方法是返回包含要返回的数据的对象。大卫的[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());
}
第三种方法就是将方法分解为两种。这可能是也可能不可行。
答案 2 :(得分: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
的新实例并将其返回,并填充返回值。
(使用Generics作为ResultContainer
留给读者的练习。)
答案 3 :(得分:3)
通过使用泛型,可以将更优雅的持有者类重用于任何类型的对象:
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)
。
答案 4 :(得分:2)
Java是一种基于类的面向对象语言,因此它的习惯用法倾向于创建类来封装数据及其周围的行为。
你有一个数据 - 消息 - 以某种方式获得,然后如果满足某些条件,则用其它方法完成。使该行为成为外部控制对象中的gets,ifs和其他操作的序列通常表明程序员不理解OOP。
我被限制只返回布尔值。不能抛出异常。
我建议你应该使用Fortran或C而不是Java吗?过程语言通常具有变异的惯用语并返回一个标志,这非常适合于该范例(在没有自动内存管理的情况下,调用者创建并传入一个填充的缓冲区;这允许缓冲区在安全时被释放调用者完成了它; Java不需要这样做,所以如果你看看Map.get()它会返回一个String,如果它失败则返回null - 不需要管理调用者的内存)。至少,不要试图在惯用的Java中找到可接受的方法 - 有了这些限制,它就不会,并且强迫它们在你身上的人做了一个糟糕的选择,这意味着你要么有黑客攻击,或者最终使用详细的代码试图制作一个非hacky解决方案。
答案 5 :(得分:1)
您不能将字符串用作输出参数。这样做的方法是使用StringBuilder类,或者为失败返回null。
答案 6 :(得分:1)
字符串是不可变的,所以是的,您需要将String包装在StringHolder中。您可以像
一样编写自己的 class StringHolder
{
String msg;
}
StringHolder sMsg = new StringHolder();
sMsg.msg = "";
if (GetMessage(sMsg))
{
System.out.println(sMsg.msg);
}
答案 7 :(得分: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可能是规范的方法。
答案 8 :(得分:1)
这是一个奇怪的要求。
为什么不以正确的方式(或者至少是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#编写的代码(很少顺便说一下)
答案 9 :(得分:0)
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中的消息字符串()。
但是,可能完全偏离基地。 : - )
答案 10 :(得分:0)
首先你要编写程序并从代码中创建它们:
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");
}
这样你就可以像其他程序那样使用程序了。最好使代码可以重用。从我这里拿走它,我已经在这里多年了。这就是专业人士如何制作代码。