Вы можете сделать это, используя отражение с чем-то вроде этого:
val b = B("foo")
val c = b.copy()
println(b.i) // prints 1
val field = classOf[A].getDeclaredFields.head
field.setAccessible(true)
field.setInt(c, 2)
println(c.i) // prints 2
Но будьте осторожны, это не просто «плохая практика программирования», а скорее полный разрыв договора .
Ваша декларация case class B(s: Sting) extends A(1)
обещает, что все экземпляров B
будут всегда иметь i
, равное 1, что является ложью.
Не говоря уже о забавных фактах, таких как b == c
- true
или c.copy.i
- 1 и т. Д. Не делайте этого.
Я думаю, что Вы достаточно близки с объявлением, которое Вы имеете там (см. ниже для эскиза). Однако при помощи небобового подхода, Вы, вероятно, потеряете поддержку, оказанную большинством инструментов, которые предполагают, что протокол JavaBeans в действительности. Будьте добры. Код ниже первое, что пришло на ум...
public class Property<T> {
public final String name;
T value;
private final PropertyChangeSupport support;
public static <T> Property<T> newInstance(String name, T value,
PropertyChangeSupport support) {
return new Property<T>(name, value, support);
}
public static <T> Property<T> newInstance(String name, T value) {
return newInstance(name, value, null);
}
public Property(String name, T value, PropertyChangeSupport support) {
this.name = name;
this.value = value;
this.support = support;
}
public T getValue() { return value; }
public void setValue(T value) {
T old = this.value;
this.value = value;
if(support != null)
support.firePropertyChange(name, old, this.value);
}
public String toString() { return value.toString(); }
}
и затем разрешение и использование это:
public class Customer {
private final PropertyChangeSupport support = new PropertyChangeSupport();
public final Property<String> name = Property.newInstance("name", "", support);
public final Property<Integer> age = Property.newInstance("age", 0, support);
... declare add/remove listenener ...
}
Customer c = new Customer();
c.name.setValue("Hyrum");
c.age.setValue(49);
System.out.println("%s : %s", c.name, c.age);
Так, теперь объявление свойства является одной строкой кода, и поддержка изменения свойства включена. Я назвал методы setValue () и getValue (), таким образом, он будет все еще похож на боб для кодирования как Носорог и материал, но для сжатого, Вы могли добавить, просто получают () и устанавливают (). Остальное оставляют как осуществление для читателя:
Также обратите внимание, что можно разделить на подклассы (обычно как анонимный класс) и переопределить setValue () для обеспечения дополнительной проверки параметра.
Я не думаю, что можно действительно убежать "От строковых ссылок", так как это в значительной степени что отражение все о.
Печально, хотя, в этот день и возраст, это все еще отчасти похоже на программирование в блоке... Groovy, C#, и т.д., и т.д. может все еще быть лучшим выбором, если у Вас есть выбор.
Проверьте мои Бобовые аннотации в
http://code.google.com/p/javadude/wiki/Annotations
В основном Вы делаете вещи как:
@Bean(
properties={
@Property(name="name"),
@Property(name="phone", bound=true),
@Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
}
)
public class Person extends PersonGen {}
вместо того, чтобы определять все, дополнительные получают/устанавливают и т.д. методы самостоятельно.
Существуют другие атрибуты для определения, равняется/хэш-код, наблюдатели, делегаты, mixins, и т.д.
Это - ряд аннотаций и процессора аннотации, который работает в затмении или в сборке командной строки (у муравья, например). Процессор генерирует суперкласс для содержания всего сгенерированного кода (процессоры аннотации не могут изменить класс, содержащий аннотации, btw),
Можно хотеть проверить Groovy - с динамическим контролем типов, основанное на JVM (и полностью совместимый с Java) язык с "реальными" свойствами.
Используйте Платформу Spring. Его цель состоит в том, чтобы упростить разработку Java путем абстракции большого количества основы, на которую Вы жалуетесь.
Можно использовать его с, в спящем режиме, который упростит взаимодействие с источниками данных для Вас.
Полезные сайты:
www.springsource.org/download
www.hibernate.org/
Для сети я предложил бы JSON (Объектная нотация JavaScript),
легкий формат обмена данными
. Здесь ссылка к JSON? Бобовый переводчик.
Вы могли также создать генератор кода, который создает Ваши .java классы из DSL, который Вы пишете. У Вас могла быть некоторая разметка, которая описывает название Вашего класса, свойства, которые Вы хотите, и их типы. Затем обработайте тот файл с программой, которая генерирует Ваш javabeans. Или Вы могли использовать аннотацию и выполнить последующую обработку файлы класса с помощью чего-то как ASM для введения средств доступа и мутаторов. Я полагаю также, что Spring обеспечивает некоторые из подобных функций, но я не использовал их.
После того как я попробовал это:
interface IListenable {
void addPropertyChangeListener( PropertyChangeListener listener );
void removePropertyChangeListener( PropertyChangeListener listener );
}
abstract class MyBean extends IListenable {
public abstract void setName(String name);
public abstract String getName();
// more things
}
public class JavaBeanFactory {
public <T> Class<T> generate(Class<T> clazz) {
// I used here CGLIB to generate dynamically a class that implements the methods:
// getters
// setters
// addPropertyChangeListener
// removePropertyChangeListener
}
}
Я использовал это в качестве этого (это - просто пример):
public class Foo {
@Inject
public Provider<MyBean> myBeanProvider;
public MyBean createHook(MyBean a) {
final MyBean b = myBeanProvider.get();
a.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
b.setName((String) evt.getNewValue());
}
});
return b;
}
}
Когда я впервые использовал C #, мне понравились свойства, но теперь, после некоторого времени использования их с VS 2008, я должен сказать, что предпочитаю set- / get-методы.
Главное - мой личный стиль работы. Когда у меня есть новый класс и я хотел бы знать, что я могу с ним сделать, я просто набираю classname.set, и Eclipse показывает мне, какие «Свойства» я могу изменить. То же самое и с получением. Возможно, это просто плохой способ VS, но там мне нужно пролистать длинный список этого itelisense (где все смешано, вместо того, чтобы сначала показывать свойства), чтобы узнать после компиляции, что свойство, которое я хотел установить, доступно только для чтения. ..doh!
Да, в Java вам нужно много строк, но я просто пишу свои атрибуты и говорю IDE: «Пожалуйста, создайте для меня геттеры и сеттеры». Но эти методы обычно занимают много места,