Метод вызывает неэффективный новый конструктор String () из FindBugs - PullRequest
0 голосов
/ 06 апреля 2019

Спасибо за помощь заранее, так как я очень плохо знаком с кодированием и просто тестирую новый код из того, что я узнал до сих пор.

    public static void main(String[] args) {
    // TODO code application logic here
    String x = new String();
    String y = new String();
    int x1;
    int y1;

    System.out.println("Welcome");
    System.out.println("Enter x prediction");
    Scanner scanstr = new Scanner (System.in);
    Scanner scanint = new Scanner (System.in);
    x = scanstr.nextLine();     

    System.out.println("Enter y prediction");
    y = scanstr.nextLine();

Когда я запускаю FindBugs для этого кода, я получаю (для строк 'x' и 'y'):

"Метод вызывает неэффективный новый конструктор String () Создание нового объекта java.lang.String с использованием конструктора без аргументов приводит к бесполезной трате памяти, поскольку созданный таким образом объект будет функционально неотличим от пустой строковой константы "". Java гарантирует, что идентичные строковые константы будут представлены одним и тем же объектом String. Поэтому вы должны просто использовать пустую строковую константу напрямую. "

Я знаю, что могу напрямую объявить x как "String x" без 'new String ()', но есть ли другой способ оптимизации кода без избавления от 'new String ()'

Ответы [ 2 ]

2 голосов
/ 06 апреля 2019

Существует в основном 3 способа написания кода:

Ваша версия:

String x = new String();

Рекомендуемая версия 1 FindBugs

String x = "";

Самая эффективная версия 2 :

String x;  // No initialization is needed when the first thing we will do
           // with 'x' is to assign a (real) value to it

Вы также можете переместить объявление, чтобы вы могли написать последнюю версию как:

String x = scanner.nextLine();

Другие версии, скорее всего, являются производными от первой версии, которые еще менее эффективны. (Они могут остановить FindBugs от жалоб, но это плохая идея.)

Есть ли другой способ оптимизации кода без избавления от 'new String ()'

Нет. Смотри выше.

Смысл FindBugs в том, что неэффективно использовать конструктор String(), и почти во всех случаях это не нужно.

Это также, вероятно, неэффективно и (IMO) определенно плохо для читабельности без необходимости инициализировать локальную переменную. Однако стоимость new String() намного превышает стоимость ненужной инициализации.

(Единственные случаи, когда может потребоваться использовать new String(), это когда ваше приложение сознательно реализовано для использования String идентификатора объекта (например, вы используете == для сравнения строк) и вам нужно иметь несколько отдельные String экземпляры "строки нулевой длины". Мне трудно думать о реальных приложениях, где вы бы хотели это сделать.)


1 - FindBugs рекомендует альтернативу. Это не «говорит тебе» что-то делать. Помните, что рекомендации такого инструмента, как FindBugs, обычно основаны на простой эвристике и не всегда являются лучшим решением.

2 - Я должен квалифицировать это. Возможно ... даже вероятно ... что JIT-компилятор заметит, что эта инициализация не нужна, и не выдаст никаких инструкций собственного кода для этого. Это сделало бы аргумент спорным. На самом деле, даже возможно, что JIT-компилятор может выполнить аналогичную оптимизацию для первой версии ... поскольку он может знать, что конструктор String() не имеет побочных эффектов. Однако обратите внимание, что эти оптимизации применяются только в тех случаях, когда инициализация не требуется. JIT-компилятору не разрешается оптимизировать new String() до "" ..., поскольку они на самом деле означают разные вещи.

0 голосов
/ 07 апреля 2019

Спасибо, ребята, за все ответы и разъяснения. Я изменил код "Строка х;" после запуска FindBugs, чтобы он не жаловался, и хотел убедиться, что это эффективно. Я также попробую 'String x = scanner.nextLine ();' просто чтобы посмотреть, как это работает со всем моим кодом.

Еще раз спасибо, я ценю ваш ответ!

...