2008-12-08 11 views
11

Jestem trochę nowy w adnotacjach Java 5 i jestem ciekawy, czy jedno z nich jest możliwe:Czy istnieje sposób używania adnotacji w języku Java do zastępowania akcesorów?

Ta adnotacja wygeneruje dla ciebie prosty getter i seter.

@attribute 
private String var = ""; 

@NotNull adnotacja oznacza, że ​​zmienna connot być null, więc nie trzeba pisać, że standardowy kod za każdym razem.

/* 
* @param s @NotNull 
*/ 
public void setString(String s){ 
    ... 
} 

Czy któryś z nich zadziała? Wydają mi się pierwszymi rzeczami, o których pisałbym adnotacje, gdybym mógł. Ponieważ nie widzę zbyt wiele na ich temat, kiedy czytam dokumenty, zakładam, że nie chodzi o to, o jakie adnotacje chodzi. Każdy kierunek tutaj byłby doceniony.

+0

Ładne pytanie. Te dwie rzeczy są dokładnie tym, co mam na mojej liście potrzebnych Javy od dłuższego czasu! Mamy nadzieję ... –

Odpowiedz

15

przetwarzanie Adnotacja występuje na drzewo składniowe. Jest to struktura, którą tworzy parser, a kompilator manipuluje.

Obecna specyfikacja (link to come) mówi, że procesory adnotacji nie mogą zmieniać drzewa składni abstrakcyjnej. Jedną z konsekwencji tego jest to, że nie nadaje się do generowania kodu.

Jeśli chcesz tego rodzaju funkcjonalność, spójrz na XDoclet. To powinno dać ci proces generowania kodu, o którym myślę, że szukasz.

Dla przykładu @NonNull, JSR-305 jest set of annotations celu zwiększenia wykrywania defektów oprogramowania i zawiera @NonNull i @CheckForNull i wiele innych.

Edytuj: Project Lombok rozwiązuje dokładnie problem generowania gettera i setera.

+0

Możesz stworzyć superklasę ... Zobacz http://code.google.com/p/javadude/wiki/Annotacje –

4

Czy istnieje sposób użycia adnotacji w Java do zastąpienia akcesorów?

W skrócie, nie, kompilator Java 5/6 nie obsługuje tego i trudno byłoby stronom trzecim dodać takie wsparcie w sposób niezależny od kompilatora.

Aby uzyskać lepszy uchwyt adnotacji, zacznę od JUnit. Jeśli napiszesz kod dla wersji 3 (pre-adnotacje) i 4 (adnotacja), szybko dostaniesz wskazówki, w jaki sposób framework zastąpił kontrakt oparty na wzorach nazywania, który był oparty na adnotacjach.

do bardziej dramatyczny przykład porównać EJB 2 z EJB 3.

4

@ Atrybut, do którego się odwołujesz, zbyt nie działa z adnotacjami, ponieważ są teraz w Javie (jak zauważył jamesh).

Najprawdopodobniej jest to "properties", którego jeszcze nie ma w Javie. Ale jest teraz bardzo gorącym tematem i możemy uzyskać je w Javie 7, a może w Javie 8 (ponieważ nadal jestem w 1.4.2, to nie pomoże mi, ale może ci pomóc).

Pojawiła się interesująca dyskusja na temat implementacji właściwości z adnotacjami w Java Posse episode #219.

+0

Prawdopodobnie nie pomoże mi to zbytnio. Właśnie opuściłem java 1.4, i to tylko dla tego projektu. Ach, krwawienie Edge'a. –

+0

Lucky. Nadal muszę używać 1.2 ... –

2

Istnieje projekt o nazwie OVal i myślę, że robi to, co chcesz. http://oval.sourceforge.net/

Jeśli zapamiętuję prawo do rzeczy z wyprzedzeniem, AspectJ jest potrzebny, jednak proste sprawdzenie działa bez AspectJ. Sprawdź to.

Istnieje również Hibernate Validator, to sprawdzić też: P

2

Jest to możliwe, tylko nie tam, gdzie jesteś ich deklarowania.

Sprawdź http://code.google.com/p/javadude/wiki/Annotations.

Mam klasy odnotowany jak

package sample; 
import com.javadude.annotation.Bean; 
import com.javadude.annotation.Property; 
import com.javadude.annotation.PropertyKind; 

@Bean(properties={ 
    @Property(name="name"), 
    @Property(name="phone", bound=true), 
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST) 
}) 
public class Person extends PersonGen {} 

i generuje klasę PersonGen dla ciebie, zawierający pobierające/ustawiające itp

Procesor ma także trochę więcej. Zauważ, że pracuję nad nową wersją, która ma małe pęknięcie API z bieżącej wersji

13

Getters/Setters: Tak, jest to możliwe. Project Lombok (http://projectlombok.org/index.html) definiuje adnotacje do generowania obiektów pobierających/ustawiających i innych.

Tak na przykład

@lombok.Data; 
public class Person { 
    private final String name; 
    private int age; 
} 

Will generowania getter dla imienia (nie seter ponieważ jest to wersja ostateczna) i getter/setter dla życia. Wygeneruje również equals, hashCode, toString oraz zainicjowanie wymaganych pól (nazwa). Dodanie @AllArgsConstructor spowoduje wygenerowanie konstruktora inicjującego oba pola.

Istnieją inne adnotacje i parametry dające ci kontrolę nad prawami dostępu (w przypadku gdy twój getter będzie chroniony lub publiczny), nazwami (getName lub nazwa?) Itp. I jest coś więcej. Na przykład bardzo podoba mi się metoda rozszerzenia.

Lombok jest bardzo łatwy w użyciu. Wystarczy pobrać słoik i skorzystać z adnotacji, a następnie getter/setters mogą być używane w kodzie bez faktycznego opisywania. Co więcej, IDE, takie jak Netbeans, obsługują to, tak że widzisz getter/setter w uzupełnianiu kodu, nawigacji itp. Adnotacje są używane tylko podczas kompilacji, a nie podczas działania, więc nie rozpowszechniasz lomboku z twoją słoikami.

NotNull: To jest obsługiwany przez findbugs i IdeaJ IDE, może inni

1

Chociaż są czasami przydatne, jeśli jesteś poważnie brakuje atrybuty to prawdopodobnie trochę niepewnie na całość projektu OO.

Ideą projektu OO jest to, że metody to "Akcje", w których proszący obiekt o zrobienie czegoś dla siebie - nie tylko ustawienie lub uzyskanie wartości - to nie jest obiekt, to struktura.

Jeśli uważasz, że brak atrybutów jest poważnym problemem, zdecydowanie zalecamy, aby spróbować kodowania przez jakiś czas, nigdy nie używając setterów i opierając się pobierającym.

To może na początku być trudne, ale założę się, że na samym końcu będziesz lepiej rozumiał zasady projektowania OO.

(Uwaga: istnieją rzadkie sytuacje, w których należy wykonać operacje typu "setter" po skonstruowaniu obiektu - najczęściej gdy trzeba utworzyć dwa obiekty, które się do siebie nawzajem odwołują. wzorzec budowniczego, w którym setery muszą zostać wywołane jeden raz i są chronione przed dwukrotnym wywołaniem)

+0

Po prostu muszę się z tobą nie zgodzić. Często potrzebuję zrobić więcej, niż ustawić właściwość w ustawiaczu (sprawdzanie wartości zerowych, inne sprawdzanie ograniczeń danych) i robię praktykę sprawdzania list pustych w pobierających i zwracania pustych list zamiast (wśród innych kontroli poprawności). Ponieważ mam taki nawyk, wolę, aby wszystkie zostały ustawione i otrzymały ten sam mechanizm, akcesory. Ponadto, jeśli masz inne osoby współpracujące z Twoim kodem, zmiana interfejsu, ponieważ zdecydujesz, że chcesz przeprowadzić jakąś walidację po fakcie, stanie się bardzo męcząca bardzo szybko. Dzięki za ocenę. –

+0

Setery automatycznie zmieniają obiekt. Niezmienna jest zawsze preferowana, więc domyślne ustawienie setterów jest z grubsza automatycznie złą praktyką. Getters - meh, jak już mówiłem, czasami konieczne, ale nie powinno być automatyczne. Ponadto, jeśli są one poza trywialne, to nie są już setters i pobierają, są one pełnoprawnymi metodami - kocham je! –

+0

@Jason, ale przy okazji, nie jesteś sam. Więcej osób nie zgadza się z tym stwierdzeniem, niż z każdym innym. Zwykle trzeba to zobaczyć kilka razy, myśleć o tym przez kilka miesięcy i bez nich realizować przez jakiś czas, zanim naprawdę zdasz sobie sprawę z korzyści, jakie twój kod czerpie z unikania ich. –

Powiązane problemy