Java: динамические свойства
Дамы И Господа,
Я новичок в Java, простите меня, если это очевидно, но я не нашел много об этом.
ID, как создать динамические свойства (переменные) класса во время выполнения (определите объект, который может быть изменен во время выполнения, путем добавления или изменения свойств и методов).
причина: я хочу сохранить модель данных в GAE, которая может быть расширена динамически после компиляции приложения (да, хранилище данных позволяет это). Какое свойство должны быть добавлены хранятся в хранилище данных, а также (его, как с помощью роботов для построенных роботов...смешной.)
Python позволяет мне добавлять свойства во время выполнения. Groovy, кажется, позволяет это тоже. Единственное, что в" чистом "мире Java указывает в этом направлении, кажется, "динамические Прокси".
но я еще не мог понять, делают ли они трюк.
5 ответов
Java не имеет возможности динамически добавлять свойства. Не имеет возможность динамически создавать классы во время выполнения или изменять их во время выполнения. Java сильно и статически типизирован. Лучшее, что вы можете сделать, это поместить такие свойства в Map
или аналогичные.
Edit: хорошо, по-видимому, некоторые разъяснения в порядке. В ОП конкретно упоминается GAE, который нет из этих методов будет работать, но я упомяну их, так как некоторые кажутся чтобы возразить против их отсутствия.
на API компилятора Java (Java 6+) позволяет компилировать классы Java во время выполнения. Технически вы можете написать исходный файл Java, чтобы выглядеть именно так, как вы хотите, скомпилировать его и загрузить.
байт-код Java-библиотек можно переписать в Java. Это используется такими библиотеками, как JPA (и другими). Вы можете изменить классы таким образом.
что OP имеет в виду, однако, a) в отношении работы на GAE и b) больше в порядке того, как Javascript позволяет изменять классы или конкретные экземпляры во время выполнения путем динамического добавления, удаления или изменения свойств. Java, конечно, не делает этого и конкретно не делает на GAE.
вышеизложенное не является исключением из этого, как и приведение класса к char *
в C++, чтобы вы могли читать частные члены, не означает, что C++ не имеет частных членов. Вы по существу обходите Java runtime с обоими этими методами даже хотя они являются частью Java.
Java не поддерживает его. Лучше всего хранить / управлять в некотором внешнем хранилище данных, к которому вы можете получить доступ изнутри кода Java. В качестве основного и встроенного примера вы можете использовать java.util.Properties
API, который вы загружаете по каждому запросу или кэшируете и перезагружаете через определенные интервалы времени или перезагружаете программно. Затем вы можете сохранить пары ключ-значение в .properties
файл, который вы просто помещаете в путь к классам. вот Sun учебник по этой теме.
A файл свойств может выглядеть как
key1=value1 key2=value2 key3=value3
если вы поместите его в classpath, то вы можете загрузить его как
Properties properties = new Properties();
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
properties.load(classLoader.getResourceAsStream("file.properties"));
String key1 = properties.getProperty("key1"); // value1
другими альтернативами являются, например, XML-файлы (к которым вы можете получить доступ с помощью любого JAVA XML API) или просто база данных (к которой вы можете получить доступ с помощью JDBC API).
Я не знаю, является ли это опцией на GAE (я не проверял ограничения), и если это будет соответствовать вашим потребностям, но, возможно, посмотрите на BeanGenerator
класс из CGLIB (альтернатива уродливому DynaBean
С BeanUtils). Цитата "смерть DynaBeans" (взгляните на сообщение):
Не один, чтобы мой CGLIB золотой молоток пропадать, я проверил в классе BeanGenerator в CVS. Вы использовать это вроде так:
BeanGenerator bg = new BeanGenerator(); bg.addProperty("foo", Double.TYPE); bg.addProperty("bar", String.class); Object bean = bg.create();
сгенерированный класс является реальные JavaBean, что означает, что вы можете использовать стандартные утилиты фасоли. Это включает все классы в (
BeanCopier
,BeanMap
иBulkBean
). Сделайте свою часть, чтобы положить конец тирании Динабианцы!
возможно использование динамических Прокси. Это также возможно сделать на GAE.
сначала создайте класс "SomeObject", который предоставляет методы для получения и установки значений свойств (т. е. getProperty(name) и setProperty(name, value)).
затем создайте интерфейс "PropertyModel", содержащий методы, которые вы хотели бы, чтобы ваши сгенерированные объекты имели.
Вызовите TransparentProxy.newInstance (someObjectInstance, MyPropertyModel.класса) для создания динамический прокси.
что происходит, так это то, что Java расширит ваш объект someObjectInstance с указанным интерфейсом (btw. вы можете указать более одного). Когда вы вызываете метод на прокси-объект, вызов метода будет перенаправлен на "вызов(...) "метод, определенный ниже, вам нужно будет изменить этот код для обработки как геттеров, так и сеттеров и включить некоторую обработку исключений и т. д. Но в целом, это способ работы динамических прокси в Java.
public class TransparentProxy implements InvocationHandler
{
private final SomeObject someObject;
private TransparentProxy(SomeObject someObject)
{
this.someObject = someObject;
}
public static Object newInstance(SomeObject someObject,
Class<? extends PropertyModel> propertyModel)
{
return Proxy.newProxyInstance(someObject.getClass().getClassLoader(),
new Class[] { propertyModel }, new TransparentProxy(someObject));
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
return this.someObject.getProperty(method.getName());
}
}
здесь DynaClass библиотека, которая может быть использована таким образом для динамического создания JavaBeans
Map<Object, Object> properties = new HashMap<Object, Object>();
roperties.put("title", "The Italian Job");
roperties.put("dateOfRelease", "new GregorianCalendar(1969, 0, 1).getTime()");
Object movieBean = BeanCreator.createBeanFromMap(properties);