Nano Hash - криптовалюты, майнинг, программирование

Java Reflection для установки атрибутов

У меня есть класс, который имеет много атрибутов settable/gettable. Я бы хотел использовать reflection для установки этих атрибутов, но у меня есть 2 вопроса о моей реализации

Вот урезанный код из моего класса

class Q {

  public String question_1;
  public String question_2;
  public String question_3;
  public String answer_1;
  public String answer_2;
  public String answer_3;
  //etc. etc.  Many String attributes

  // … constructor and other stuff are omitted

  // here is my method for "dynamically" setting each attribute
  public void set_attribute(String a_raw_string, String my_field) {
    try {
      Class cls = Class.forName("com.xyz.models.Q");
      Field fld = cls.getField(my_field);
      fld.set(this, a_raw_string);
  }
  catch (Throwable e) {
      System.err.println(e);
  }
}

Затем я устанавливаю различные поля следующим образом:

Q q = new Q();
q.set_attribute("abcde", "question_1");
q.set_attribute("defgh", "question_2");
// etc.

Это работает (т. е. переменные экземпляра устанавливаются, когда я вызываю set_attribute.

Однако они работают только тогда, когда переменные экземпляра объявлены общедоступными. Когда они объявляются закрытыми, я получаю NoSuchFieldException.

ВОПРОС 1. Почему я получаю эту ошибку, когда поля закрыты? Мое наивное предположение состоит в том, что, поскольку функция set_attribute является частью класса, она должна иметь неограниченный доступ к переменным экземпляра.

ВОПРОС 2: я думаю, что, возможно, слишком много думаю об этой проблеме (т. е. мне не следует использовать отражение для установки переменных таким образом). Есть ли более рекомендуемый подход? Причина, по которой я хочу использовать отражение, заключается в том, что объявить кучу сеттер-методов — головная боль в заднице… поэтому мне интересно, решил ли кто-нибудь эту проблему лучше.

Спасибо!

15.10.2010

  • Это интересно, когда у вас есть карта пар тег/значение, и вы хотите загрузить pojo. 15.10.2010
  • Не могли бы вы объяснить, почему вы хотели бы использовать отражение или, скорее, почему вы не хотите использовать обычные сеттеры? Я спрашиваю, потому что не понимаю вашей настоящей проблемы... 15.10.2010

Ответы:


1

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

Ага. Отражение довольно медленное и должно использоваться только в крайнем случае. Если это делается просто для того, чтобы избежать большого количества избыточного кода, рассмотрите возможность использования автоматической генерации кода. Для объектов с чистыми данными я настоятельно рекомендую использовать буферы протокола; он сгенерирует геттеры/сеттеры (вам нужно только объявить поля). Кроме того, это позволяет легко обмениваться данными между C++, Java и Python.

Если у вас есть класс, который имеет много полей, но не является чистым объектом данных... хорошо

  1. Вы должны подумать, должны ли все поля быть изменяемыми. (Вам действительно нужны сеттеры?)
  2. Должны ли поля быть видны. (Вам вообще нужны какие-либо аксессуары?)

Часто бывает полезно сделать поля "окончательными", инициализировать их в конструкторе(ах) и не предоставлять доступ или предоставлять ограниченный доступ через реализованный интерфейс.

15.10.2010

2

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

Большинство IDE (например, Eclipse или NetBeans) включают инструменты для автоматического создания методов получения и установки для полей класса.

15.10.2010

3
  1. Когда они закрыты, вам нужно позвонить fld.setAccessible(true);
  2. Да, почему бы вам просто не установить поля напрямую и избежать отражения? Не похоже, что вы делаете что-то динамичное. Просто они частные - почему? Возможно, вы имеете в виду открыть геттеры/сеттеры и сделать поля закрытыми? Если это так, то вам следует просто вызывать публичные сеттеры.
15.10.2010
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..