Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
required fields in klasse mit annotation realisierbar?
Hallo ich möchte folgenden Mechanismus realisieren.
In meiner Anwendung habe ich Beans mit Attributen.
Nun ist es so dass ein Paar Attribute zwingend gesetzt sein müssen, andere nicht.
Es wäre fein wenn ich mir hier eine Annotation zusammenbasteln könnte. Beispielsweise eine @Required Annotation die vor jedem Attribut in der Bean steht die zwingend gesetzt sein muss. Wenns nicht gesetzt wird gibt es dann halt eine Exception oder so.
Ist das mit Annotations realisierbar? Wie gehtman sowas an? Oder sollte ich da einen anderen Weg gehen?
ja das war auch mein erster Gedanke. Allerdings wäre das mit einer Annotation sehr viel schöner, jedoch habe ich nicht wirklich Ahnung ob man Annotation dafür benutzen kann....
import java.lang.reflect.Field;
public class AParser
{
public static void checkFields(Object obj)
{
Field[] felder = obj.getClass().getDeclaredFields();
for(Field f : felder) {
if(f.isAnnotationPresent(Required.class)) {
boolean accessible = f.isAccessible();
f.setAccessible(true);
try {
if(f.get(obj) == null) {
throw new IllegalArgumentException(obj.getClass().getSimpleName() + "." + f.getName() + " darf nicht null sein");
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
f.setAccessible(accessible);
}
}
}
}
Required.java
Java:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Required
{
}
Demo.java
Java:
public class Demo
{
@Required
private String name;
public static void main(String[] args)
{
Demo demo1 = new Demo();
Demo demo2 = new Demo();
demo1.name = "Tomate Salat";
System.out.println("Check demo1");
AParser.checkFields(demo1);
System.out.println("Check demo2");
AParser.checkFields(demo2);
}
}
Ausgabe:
Code:
Check demo1
Check demo2
Exception in thread "main" java.lang.IllegalArgumentException: Demo.name darf nicht null sein
at AParser.checkFields(AParser.java:17)
at Demo.main(Demo.java:21)
@Bygones:
ouh ja, garnicht gesehen, dass IllegalArgumentException unchecked ist.
Geht es dir darum, dass nur gültige Objekte erzeugt werden dürfen? -> Factory
Falls du Validierungen von u.U. mehrfach zu setztenden Werten durchführen möchtest, geht das eben mit Annotationen oder if Abfragen die Exceptions werfen.
public class Demo {
String name;
}
public final class DemoFactory {
private DemoFactory() {
// static
}
public static Demo createDemo(String name) {
Demo d = new Demo();
d.name = name;
return d;
}
}
durch das Bereitstellen einer Factory hast du die Möglichkeit eben bestimmte dinfe zu forsieren.
Andere Lösung wäre, mit final Feldern zu arbeiten und diese dann logischerweise durch den Konstruktor direkt zu setzen. (Geht dann aber natürlich nur, wenn man keinen Konstruktor ohne Parameter braucht.)
public class Test {
// str must not be null
private final String str;
public Test(String str){
this.str = str;
}
public static void main(String[] args) {
new Test(null);
}
}
Die einzigen Möglichkeiten wirklich sicher zu stellen das Objekte richtig erzeugt werden ist über eine Factory die die Argumente prüft, von Konstruktoren Excepeptions werfen wenn die Argumente nicht gültig sind oder halt das Objekt nach der Initialisierung zu überprüfen - dann kann man natürlich den Weg gehn wie ihn TS schon beschrieben hat.