Java: выход со старым, внутри с новым

Java близится к версии 7. Мне приходит в голову, что должно быть много учебников и учебных пособий, которые начинают использовать методы обучения, основанные на более старых версиях Java, где методы обучения будут иметь гораздо лучшие решения.

Каковы некоторые ситуации с шаблоном кода, особенно те, которые вы видите, люди реализуют с помощью привычки, что вы обнаружите, что рефакторинг используется для использования последних версий Java?

Ответ 1

Перечисления. Замена

public static final int CLUBS = 0;
public static final int DIAMONDS = 1;
public static final int HEARTS = 2;
public static final int SPADES = 3;

с

public enum Suit { 
  CLUBS, 
  DIAMONDS, 
  HEARTS, 
  SPADES 
}

Ответ 2

Generics и больше не нужно создавать итератор для прохождения всех элементов в коллекции. Новая версия намного лучше, проще в использовании и понятна.

EDIT:

До:

List l = someList;
Iterator i = l.getIterator();
while (i.hasNext()) {
    MyObject o = (MyObject)i.next();
}

После

List<MyObject> l = someList;
for (MyObject o : l) {
    //do something
}

Ответ 3

Использование локальных переменных типа StringBuffer для выполнения конкатенации строк. Если не требуется синхронизация, теперь рекомендуется использовать StringBuilder, потому что этот класс обеспечивает лучшую производительность (предположительно потому, что он несинхронизирован).

Ответ 4

чтение строки со стандартного ввода:

Java pre-5:

try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String str = reader.readLine();
    reader.close();
}
catch (IOException e) {
    System.err.println("error when closing input stream.");
}

Java 5:

Scanner reader = new Scanner(System.in);
String str = reader.nextLine();
reader.close();

Java 6:

Console reader = System.console();
String str = reader.readLine();

Ответ 5

Вот что я вижу:

String.split() по сравнению с StringTokenizer.

StringTokenizer не рекомендуется для нового кода, но я все еще вижу, как люди его используют.

Что касается совместимости, Sun прилагает огромные усилия, чтобы Java была совместима с предыдущим и предыдущим. Это частично объясняет, почему дженерики настолько сложны. Предполагается также, что устаревание облегчит переход от старого к новому.

Ответ 6

Старый код, использующий Thread вместо многих других альтернатив Thread... в наши дни, очень мало кода, который я запускаю, по-прежнему нужно использовать поток raw. Они лучше обслуживались бы уровнем абстракции, особенно Callable/Фьючерсы/Executors.

См:

java.util.Timer

javax.swing.Timer

java.util.concurrent. *

Ответ 7

Также могут быть полезны VARARGS.

Например, вы можете использовать:

public int add(int... numbers){
    int sum = 0 ;
    for (int i : numbers){
        sum+=i;
    }
    return sum ;
}

вместо:

public int add(int n1, int n2, int n3, int n4) ;

или

public int add(List<Integer> numbers) ;

Ответ 8

Использование локальных переменных типа Vector для хранения списка объектов. Если синхронизация не требуется, теперь рекомендуется использовать реализацию List, такую ​​как ArrayList, потому что этот класс обеспечивает лучшую производительность (поскольку он несинхронизирован).

Ответ 9

Форматированная печать была введена уже в JDK 1.5. Поэтому вместо использования:

String str = "test " + intValue + " test " + doubleValue;

или эквивалент с помощью StringBuilder,

можно использовать

String str = String.format("test %d test %lg", intValue, doubleValue);

Последнее гораздо читаемо, как из конкатенации строк, так и из версий строковых построителей. Тем не менее я считаю, что люди принимают этот стиль очень медленно. Например, система Log4j не использует это, хотя я считаю, что это было бы очень полезно для этого.

Ответ 10

Явное преобразование между примитивными и оболочными типами (например, Integer to int или наоборот), которое автоматически берется с помощью autoboxing/unboxing с Java 1.5.

Примером является

Integer myInteger = 6;
int myInt = myInteger.intValue();

Можно просто написать как

Integer myInteger = 6;
int myInt = myInteger;

Но обратите внимание на NullPointerExceptions:)

Ответ 11

Q1: Ну, наиболее очевидные ситуации встречаются в коллекциях generics/type specific. Другой, который сразу же приходит на ум, - это улучшенный цикл, который, как мне кажется, выглядит более чистым и понятным.

Q2: В общем, я связывал JVM вместе с моим приложением для приложений, ориентированных на клиента. Это позволяет нам использовать новые языковые функции, не беспокоясь о несовместимости JVM.

Если бы я не связывал JRE, я бы, вероятно, придерживался 1.4 по соображениям совместимости.

Ответ 12

Простое изменение с 1.5, но делает небольшую разницу - в Swing API, доступ к contentPane JFrame:

myframe.getContentPane().add(mycomponent);

становится

myframe.add(mycomponent);

И, конечно же, введение Enums изменило то, как многие приложения, в которых раньше использовали константы.

String.format() значительно улучшила манипуляции с строками, и оператор trernary if весьма полезен для упрощения чтения кода.

Ответ 13

Общие коллекции делают кодирование намного более устойчивым к ошибкам. OLD:

Vector stringVector = new Vector();
stringVector.add("hi");
stringVector.add(528); // oops!
stringVector.add(new Whatzit());  // Oh my, could spell trouble later on!

NEW:

ArrayList<String> stringList = new ArrayList<String>();
stringList.add("hello again");
stringList.add(new Whatzit()); // Won't compile!

Ответ 14

Использование Iterator:

List list = getTheList();
Iterator iter = list.iterator()
while (iter.hasNext()) {
  String s = (String) iter.next();
    // .. do something
}

Или иногда видна альтернативная форма:

List list = getTheList();
for (Iterator iter = list.iterator(); iter.hasNext();) {
  String s = (String) iter.next();
  // .. do something
}

Теперь все заменены на:

List<String> list = getTheList();
for (String s : list) {
  // .. do something
}

Ответ 15

Хотя я признаю, что статический импорт можно легко переоценить, мне нравится использовать

import static Math.* ;

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

Ответ 16

Преобразование числа в строку:

String s = n + "";

В этом случае я думаю, что всегда был лучший способ сделать это:

String s = String.valueOf(n);

Ответ 17

копирование существующего массива в новый массив:

pre-Java 5:

int[] src = new int[] {1, 2, 3, 4, 5};
int[] dest = new int[src.length];
System.arraycopy(src, 0, dest, 0, src.length);

Java 6:

int[] src = new int[] {1, 2, 3, 4, 5};
int[] dest = Arrays.copyOf(src, src.length);

раньше мне приходилось явно создавать новый массив, а затем копировать исходные элементы в новый массив (вызывая метод с большим количеством параметров). теперь синтаксис чист, и новый массив возвращается из метода, мне не нужно его создавать. Кстати, метод Arrays.copyOf имеет вариацию под названием Arrays.copyOfRange, который копирует конкретный регион исходного массива (в значительной степени похожий на System.arraycopy).

Ответ 18

Новая конструкция for -each для перебора массивов и коллекций является самой большой для меня.

В эти дни, когда я вижу цикл шаблона for для повторения по массиву один за другим с использованием индексной переменной, мне хочется кричать:

// AGGHHH!!!
int[] array = new int[] {0, 1, 2, 3, 4};
for (int i = 0; i < array.length; i++)
{
    // Do something...
}

Замена выше на for конструкция, введенная в Java 5:

// Nice and clean.    
int[] array = new int[] {0, 1, 2, 3, 4};
for (int n : array)
{
    // Do something...
}

Чистый, лаконичный и, самое главное, он дает смысл коду, а не показывает, как что-то делать.

Очевидно, что код имеет смысл итерации по коллекции, а не старый цикл for, говорящий о том, как перебирать массив.

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

Ответ 19

Связано с varargs; метод утилиты Arrays.asList(), который, начиная с Java 5, принимает параметры varargs, очень полезен.

Я часто обнаруживаю, что упрощаю что-то вроде

List<String> items = new ArrayList<String>();
items.add("one");
items.add("two");
items.add("three");
handleItems(items);

используя

handleItems(Arrays.asList("one", "two", "three"));

Ответ 20

Аннотация

Интересно, что никто не упоминал об этом до сих пор, но многие фреймворки полагаются на аннотации, например Spring и Hibernate. Сегодня для описания файлов конфигурации xml часто используются аннотации кода (хотя это означает, что вы теряете гибкость при переходе от конфигурации к метакоду, но часто правильный выбор). Лучшим примером является EJB 2 (и старше) по сравнению с EJB 3.0 и как упрощение программирования EJB благодаря аннотациям.

Я считаю, что аннотации также очень полезны в сочетании с некоторыми инструментами AOP, такими как AspectJ или Spring AOP. Такая комбинация может быть очень сильной.

Ответ 21

Изменение тестов JUnit 3-стиля:

class Test extends TestCase {
    public void testYadaYada() { ... }
}

для тестов JUnit 4-стиля:

class Test {
   @Test public void yadaYada() { ... }
}

Ответ 22

Улучшенные одноэлементные паттерны. Технически они охватываются популярными ответами, но это значимая подкатегория.

public enum Singleton {
    INSTANCE;

    public void someMethod() {
        ...
    }
}

чище и безопаснее, чем

public class Singleton {
    public static final Singleton INSTANCE = new Singleton();

    private Singleton() {
        ...
    }

    public void someMethod() {
        ...
    }
}

Ответ 23

Преобразование классов в использование дженериков, что позволяет избежать ситуаций с ненужными приведениями.

Ответ 24

Я немного опасаюсь рефакторировать эти строки, если это все, что вы делаете с вашим исходным деревом. Примеры до сих пор не кажутся одними причинами для изменения любой рабочей базы кода, но, возможно, если вы добавляете новую функциональность, вы должны использовать все новые вещи.

В конце дня, эти примеры на самом деле не снимают код плиты котла, они просто используют более управляемые конструкции новых JDK для делают приятный код котельной плиты strong > .

Большинство способов сделать ваш код элегантным не в JDK.

Ответ 25

Хорошо, теперь моя очередь кричать.

Я не рекомендую 90% этих изменений.

Не то, чтобы это не очень хорошая идея использовать их с новым кодом, но взломать существующий код, чтобы изменить цикл for на цикл for (:) - это просто пустая трата времени и шанс что-то сломать. (IIWDFWI) Если это работает, не исправляйте это!

Если вы находитесь в реальной компании-разработчике, это изменение теперь становится чем-то вроде проверки кода, тестирования и, возможно, отладки.

Если кто-то, кто делает такой рефакторинг без причины, вызвал проблему ЛЮБОГО рода, я бы не дал им окончательного дерьма.

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

Кроме того, всем предложениям от имени "Производительность" действительно нужно узнать о законах оптимизации. В двух словах: "Не делай! Когда-либо! (Google" Правила оптимизации, если вы мне не верите").

Ответ 26

Использование Swing new DefaultRowSorter для сортировки таблиц по сравнению с переносом вашего собственного с нуля.

Ответ 27

Новая версия Java редко нарушает существующий код, поэтому просто оставляйте только старый код и сосредоточьтесь на том, как новая функция упрощает вашу жизнь.

Если вы просто оставите старый код один, то писать новый код с помощью новых функций не так страшно.

Ответ 28

Сравнение строк, действительно старые школьные Java-программисты, с которыми я встречался, будут делать:

String s1 = "...", s2 = "...";

if (s1.intern() == s2.intern()) {
    ....
}

(предположительно по соображениям производительности)

В то время как в наши дни большинство людей просто делают:

String s1 = "...", s2 = "...";

if (s1.equals(s2)) {
    ....
}

Ответ 30

Стоит отметить, что Java 5.0 существует уже пять лет, и с тех пор произошли незначительные изменения. Вам нужно будет работать с очень старым кодом, чтобы все еще рефакторировать его.