java - Выход-1 становится косой чертой в цикле




string while-loop (2)

Не знаю, почему Java выдает такой случайный вывод, но проблема в вашей конкатенации, которая не работает для больших значений i внутри цикла for .

Если вы замените String value = i + ""; строка со String value = String.valueOf(i) ; ваш код работает как положено.

Конкатенация, использующая + для преобразования int в строку, является нативной и может содержать ошибки (как ни странно, мы ее сейчас, вероятно, нашли) и вызывает такую ​​проблему.

Примечание: я уменьшил значение i внутри цикла for до 10000, и у меня не возникало проблем с + конкатенацией.

Об этой проблеме необходимо сообщить заинтересованным сторонам Java, и они могут высказать свое мнение о них.

Изменить Я обновил значение i в для цикла до 3 миллионов и увидел новый набор ошибок, как показано ниже:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at java.lang.Integer.getChars(Integer.java:463)
    at java.lang.Integer.toString(Integer.java:402)
    at java.lang.String.valueOf(String.java:3099)
    at solving.LoopOutPut.test(LoopOutPut.java:16)
    at solving.LoopOutPut.main(LoopOutPut.java:8)

Моя версия Java 8.

Удивительно, но следующий код выводит:

/
-1

Код:

public class LoopOutPut {

    public static void main(String[] args) {
        LoopOutPut loopOutPut = new LoopOutPut();
        for (int i = 0; i < 30000; i++) {
            loopOutPut.test();
        }

    }

    public void test() {
        int i = 8;
        while ((i -= 3) > 0) ;
        String value = i + "";
        if (!value.equals("-1")) {
            System.out.println(value);
            System.out.println(i);
        }
    }

}

Я пытался много раз определить, сколько раз это произойдет, но, к сожалению, это было в конечном итоге неопределенным, и я обнаружил, что результат -2 иногда превращается в период. Кроме того, я также попытался удалить цикл while и вывести -1 без проблем. Кто может сказать мне, почему?

Информация о версии JDK:

HopSpot 64-Bit 1.8.0.171
IDEA 2019.1.1

Честно говоря, это довольно странно, поскольку этот код технически никогда не должен выводиться, потому что

int i = 8;
while ((i -= 3) > 0);

... должно всегда приводить к тому, что i равно -1 (8 - 3 = 5; 5 - 3 = 2; 2 - 3 = -1). Что еще более странно, так это то, что он никогда не выводится в режиме отладки моей IDE.

Интересно, что в тот момент, когда я добавляю чек перед преобразованием в String , тогда нет проблем ...

public void test() {
  int i = 8;
  while ((i -= 3) > 0);
  if(i != -1) { System.out.println("Not -1"); }
  String value = String.valueOf(i);
  if (!"-1".equalsIgnoreCase(value)) {
    System.out.println(value);
    System.out.println(i);
  }
}

Всего два пункта хорошей практики кодирования ...

  1. Скорее используйте String.valueOf()
  2. Некоторые стандарты кодирования указывают, что литералы String должны быть целью .equals() , а не аргументом, таким образом минимизируя исключения NullPointerException.

Единственный способ, которым я этого не получил, это использование String.format()

public void test() {
  int i = 8;
  while ((i -= 3) > 0);
  String value = String.format("%d", i);
  if (!"-1".equalsIgnoreCase(value)) {
    System.out.println(value);
    System.out.println(i);
  }
}

... по сути, похоже, что Java нужно немного времени, чтобы отдышаться :)

РЕДАКТИРОВАТЬ: Это может быть совершенно случайно, но, кажется, есть некоторое соответствие между значением, которое выводится на печать и таблицы ASCII .

  • i = -1 , отображаемый символ - / (десятичное значение ASCII 47)
  • i = -2 , символ отображается . (Десятичное значение ASCII 46)
  • i = -3 , отображаемый символ - - (десятичное значение ASCII 45)
  • i = -4 , отображается символ (десятичное значение ASCII 44)
  • i = -5 , символ отображается + (десятичное значение ASCII 43)
  • i = -6 , символ отображается * (десятичное значение ASCII 42)
  • i = -7 , символ отображается ) (десятичное значение ASCII 41)
  • i = -8 , символ отображается ( (десятичное значение ASCII 40)
  • i = -9 , символ отображается как ' (десятичное значение ASCII 39)

Что действительно интересно, так это то, что символ в ASCII десятичной 48 является значением 0 а 48 - 1 = 47 (символ / ) и т. Д.





jit