Действительно ли возможно циклично выполниться через участники классов в Java?

Ограниченный объем Лучший

Использование Ваша вторая опция:

for ( ... ) {
  String s = ...;
}

Объем не Влияет на Производительность

, Если Вы демонтируете, кодируют скомпилированный от каждого (с JDK javap инструмент), Вы будете видеть, что цикл компилирует в те же самые инструкции по JVM в обоих случаях. Обратите внимание также, что Brian R. Bondy "Опция № 3" идентична Опции № 1. Ничто дополнительное не добавлено или удалено из стека при использовании более трудного объема, и те же данные используются на стеке в обоих случаях.

Избегают Преждевременной Инициализации

, единственная разница между этими двумя случаями - то, что в первом примере переменная s излишне инициализируется. Это - отдельный вопрос от местоположения объявления переменной. Это добавляет две потраченных впустую инструкции (чтобы загрузить строковую константу и сохранить ее в слоте стекового фрейма). Хороший инструмент статического анализа предупредит Вас, что Вы никогда не читаете значение, которое Вы присваиваете s, и хороший JIT-компилятор будет, вероятно, игнорировать его во времени выполнения.

Вы могли зафиксировать это просто при помощи пустого объявления (т.е. String s;), но это считают плохой практикой и имеет другой побочный эффект, обсужденный ниже.

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

Сохраняют Слоты Стека

, Как упомянуто, в то время как инструкции по JVM являются тем же в обоих случаях, существует тонкий побочный эффект, который делает его лучше всего, на уровне JVM, для использования возможного наиболее ограниченного объема. Это видимо в "таблице локальных переменных" для метода. Рассмотрите то, что происходит, если у Вас есть несколько циклов с переменными, объявленными в излишне большом объеме:

void x(String[] strings, Integer[] integers) {
  String s;
  for (int i = 0; i < strings.length; ++i) {
    s = strings[0];
    ...
  }
  Integer n;
  for (int i = 0; i < integers.length; ++i) {
    n = integers[i];
    ...
  }
}

переменные s и n могли быть объявлены в их соответствующих циклах, но так как они не, компилятор использует два "слота" в стековом фрейме. Если они были объявлены в цикле, компилятор может снова использовать тот же слот, делая стековый фрейм меньшим.

, Что Действительно Вопросы

Однако большинство этих проблем является несущественным. Хороший JIT-компилятор будет видеть, что не возможно считать начальное значение, которое Вы расточительно присваиваете и оптимизируете присвоение далеко. Сохранение слота здесь или там не собирается решать судьбу Вашего приложения.

важная вещь состоит в том, чтобы сделать Ваш код читаемым и легким поддержать, и в этом отношении, использование ограниченного объема ясно лучше. Чем меньший объем переменная имеет, тем легче постигать, как это используется и что влияет на любые изменения в коде, будет иметь.

8
задан Genia S. 30 October 2009 в 21:51
поделиться

5 ответов

Что ж, вы можете сделать это с помощью отражения:

for (Field field : clazz.getFields())
{
    ...
}

(Или эквивалент для методов и т. Д.)

Затем вы можете получить значения полей для конкретного экземпляра или статические значения.

26
ответ дан 5 December 2019 в 04:58
поделиться

Да, но это немного хлопотно.

Вы должны использовать отражение.

См .: Class.getDeclaredFieds ()

Возвращает массив полей объекты, отражающие все поля, объявленные классом или интерфейсом, представленным этим объектом Class

Вы можете увидеть пример здесь

Существует три способа получения объекта Field из объекта Class.

 Class cls = java.awt.Point.class;

 // By obtaining a list of all declared fields.
 Field[] fields = cls.getDeclaredFields();

 // By obtaining a list of all public fields, 
 // both declared and inherited.
 fields = cls.getFields();
 for (int i=0; i<fields.length; i++) {
   Class type = fields[i].getType();
   process(fields[i]);
 }

 // By obtaining a particular Field object.
 // This example retrieves java.awt.Point.x.
 try {
   Field field = cls.getField("x");
   process(field);
   } catch (NoSuchFieldException e) {
 }

См. Определение класса для дополнительных параметров.

7
ответ дан 5 December 2019 в 04:58
поделиться

Да, используйте Reflection API . В частности, проверьте методы getFields и getMethods из Class .

4
ответ дан 5 December 2019 в 04:58
поделиться

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

http://java.sun.com/j2se/1.4.2/docs/api/ java / lang / reflection / package-summary.html

0
ответ дан 5 December 2019 в 04:58
поделиться

Вы можете использовать отражение, чтобы получить все члены и функции.

Может быть, вам стоит спросить себя, почему у этого DTO так много участников, что вы считаете это необходимым. Возможно, пора провести рефакторинг.

0
ответ дан 5 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: