Использование Ваша вторая опция:
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-компилятор будет видеть, что не возможно считать начальное значение, которое Вы расточительно присваиваете и оптимизируете присвоение далеко. Сохранение слота здесь или там не собирается решать судьбу Вашего приложения.
важная вещь состоит в том, чтобы сделать Ваш код читаемым и легким поддержать, и в этом отношении, использование ограниченного объема ясно лучше. Чем меньший объем переменная имеет, тем легче постигать, как это используется и что влияет на любые изменения в коде, будет иметь.
Что ж, вы можете сделать это с помощью отражения:
for (Field field : clazz.getFields())
{
...
}
(Или эквивалент для методов и т. Д.)
Затем вы можете получить значения полей для конкретного экземпляра или статические значения.
Да, но это немного хлопотно.
Вы должны использовать отражение.
См .: 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) {
}
См. Определение класса для дополнительных параметров.
Да, используйте Reflection API . В частности, проверьте методы getFields
и getMethods
из Class
.
Взгляните на структуру отражения, с помощью которой вы можете проанализировать класс для получения этой информации.
http://java.sun.com/j2se/1.4.2/docs/api/ java / lang / reflection / package-summary.html
Вы можете использовать отражение, чтобы получить все члены и функции.
Может быть, вам стоит спросить себя, почему у этого DTO так много участников, что вы считаете это необходимым. Возможно, пора провести рефакторинг.