Java Bugs

Published: 10 Mar 2017 Category: java

记录Java开发中遇到的bugs和traps.

1. split 返回个数问题

如果两个reg之间是“”,将不会作为结果返回!

例如:

System.out.println("1.2.3. .".split("\\.").length); //4, not 5!

解决,将limit置为负数——

System.out.println("1.2.3. .".split("\\.", -1).length); //5

官方解释:

The {@code limit} parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array's length will be no greater than n, and the array's last entry will contain all input beyond the last matched delimiter. If n is non-positive then the pattern will be applied as many times as possible and the array can have any length. If n is zero then the pattern will be applied as many times as possible, the array can have any length, and trailing empty strings will be discarded.

2. hashcode 返回负值

hashcode的计算是一直累计,int越界后就变成了负值。可以取绝对值:

  int queueNamePostfix = Math.abs(jobId.hashCode() % splitQueueCount);

注意不能用Math.abs(jobId.hashCode()), 因为Math.abs(Integer.MIN_VALUE)仍旧是负值!

3. field用错

field

What a shame!

4. @Value取值为null或@Autowired注入失败

下面这段代码会出错,提示host或client为null:

  @Component
  @PropertySource("classpath:/config/config.properties")
  public class MqttServiceClient implements IMqttServiceClient {
      @Value("${mqtt_host}")
      private String host;
      @Value("${mqtt_client}")
      private String client;

      private MqttClient mqttClient;

      public MqttService(){
      mqttClient= new MqttClient(host, client, new MemoryPersistence()); 
      } 
  }

因为Java类会先执行构造方法,然后再给注解了@Value的成员变量注入值(@Autowired也一样),所以在执行构造方法的时候,就会报错。

解决方法一,把@Value注解的属性写入一个AppConfig类中,然后注入AppConfig类的对象,并用构造器注入,这样可以明确成员变量的加载顺序。

  public class MqttServiceClient implements IMqttServiceClient {
      private AppConfig appConfig;
      private MqttClient mqttClient;

      @Autowired
      public MqttServiceClient(AppConfig appConfig){
          this.appConfig = appConfig;
          mqttClient = new MqttClient (appConfig.getHost(), appconfig.getClient, new MemoryPersistence()
     }
   }

解决方法二,借助@PostConstruct延迟初始化:

  @Component
  @PropertySource("classpath:/config/config.properties")
  public class MqttServiceClient implements IMqttServiceClient {
      @Value("${mqtt_host}")
      private String host;
      @Value("${mqtt_client}")
      private String client;

      private MqttClient mqttClient;

      @PostConstruct
      public void init(){
      mqttClient= new MqttClient(host, client, new MemoryPersistence()); 
      } 
  }