java - 为什么在连接前两个对象后从多个对象创建字符串失败

标签 java multithreading

今天,我在尝试组合多个“变量”或对象时遇到了一个问题,就像下面的示例代码:

String stuff = "blah blah" + amazingness.getName() + " fantabulous code: " + address.

上面的示例正常工作,但在我的情况下不起作用。

基本上,我有一个通过 UDP 方式接收数据的服务器。现在,为了使用 UDP,我必须创建许多线程,所以应用程序不会挂起。我不知道问题是否与多线程有关,因为处理器以随机顺序随机运行线程。

我正在使用 Java 版本 1.8 update 05。 这是我的方法中的代码。

String message = "Client" + c.name + "(" + c.getID() + ") @" + c.address.toString() + ":" + c.port + "disconnected";

其中:c.name为“Classic”,c.getID()返回一个随机数,c.address.toString() 返回客户端的ip地址,c.port是客户端的端口。

当我运行代码时,我收到一条消息“Client Classic”,没有其他消息。 预期的消息是:“Client Classic(1932) @ 70.40.423.110:8112 disconnected” 这是一个屏幕截图: Screen shot of inline message

其他值去哪儿了?

现在我开始认为这可能是因为引用其他类打乱了向字符串添加更多值的过程。

所以我尝试在设置消息字符串之前获取值

String message = "";
    String name = c.name;
    int cID = c.getID();
    String address = c.address.toString();
    int port = c.port;
    message = "Client " + name + "(" + cID + ") @ " + address + ":" + port + "disconnected";

    System.out.println(message);

其中:String name为Classic,cID为随机数,address为ip地址,port 是一个端口号。所有变量都不是静态的。仍然没有输出所需的消息: Image showing the value of the message string

现在,我在没有线程的情况下再次测试它,只是一个独立的类: enter image description here

它工作得很好!现在,我的问题是为什么会出现上述结果,我做错了什么?

感谢您花时间阅读我的问题,希望您能理解。

编辑 1:我注意到,在 message 的值中,从未添加结束引号,将对其进行调查。

编辑 2:看起来错误出在 name 变量中,尽管我不知道为什么。

编辑 3:看起来 name 变量包含多个“空”字符,我会调查一下。

编辑:我相信我已经解决了这个问题,我将包含一个纲要:

  Since I created a byte array of length 1024 to send through the network, I never trimmed the array before sending.
  Calling "string.trim()" deletes the excess whitespace characters created when I set the variable "name".
  Even though I had found this out without seeing the answer from David, I'll credit him with the correct answer.

最佳答案

您只在 Eclipse 中看到这种行为吗?我怀疑正在发生的事情是您的 name 变量包含一个空 (0) 字符,这对 Java 本身来说不是问题,但可能是 SWT 的问题(Eclipse 使用的小部件工具包).

例如,以下代码创建一个用零填充的数组,用一些字母覆盖前几个 0,然后构造一个与您的示例类似的字符串。

public class TestMain {

    public static void main(String args[]) {
        byte[] badChars = new byte[10]; // all bytes are 0
        String test = "Middle";
        for (int i = 0;i < test.length() && i < badChars.length; ++i) {
            badChars[i] = (byte) test.charAt(i);
        }        
        String a = new String(badChars);        
        System.out.println(a);        
        String p = "Before " + new String(badChars) + " After";
        System.out.println(p);
    }
}

这个在eclipse中的输出是

Middle
Before Middle

但是当我在 Intellij IDEA 中运行它时,我得到了

Middle
Before Middle After

正如您所期望的那样。

当我在上面最后一个 println 之后添加以下代码时:

StringBuffer b = new StringBuffer();
for (int i = 0; i < p.length(); ++i) {
    char ch = p.charAt(i);
    if (ch > 0) {
        b.append(ch);
    }
}

System.out.println(b.toString());

我在 Eclipse 中得到以下信息

Middle
Before Middle
Before Middle After

所以我认为您的“名称”可能包含一个空字符,这会在显示时导致 SWT 问题(例如调试器,甚至是控制台)。 SWT 使用 native 小部件(可能还有 native C 风格的字符串,意思是空终止)。

希望这是有道理的 - 在打印它们之前尝试从字符串中去除空值,即使它们在 Java 中不应该很重要。

关于java - 为什么在连接前两个对象后从多个对象创建字符串失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25173573/

相关文章:

java - 如何在 Android/Java 中读取 Apache POI 中的 xlsx 文件

java - 添加通用集合排序方法时出错

Java notify() 在 wait() 之前运行?

android - 异步任务工作流程

java - 线程 : notify() and wait() in java

java - 为什么 jstack out 说线程状态是 "RUNNABLE"而 socketRead

java - Hystrix 回退方法不运行

C#:异常后停止线程

java - 错误下ThreadDeath的使用

java - Java 中 WlanEnumInterfaces(Windows Native WiFi)的奇怪返回