2015-09-08 8 views
10

Der folgende Code ist ein kleines Beispiel, das das Problem leicht reproduziert. Ich habe also eine Variable vom Typ String, für die ein Standardwert festgelegt ist. Ich habe 3 Methoden:Java Introspection - seltsames Verhalten

  • Getter
  • setter
  • bequeme Methode, die die Zeichenfolge

Die Selbstbeobachtung gibt nicht die Getter als Read boolean umwandelt und den Setter als Write. Stattdessen wird die isTest() -Methode als readMethod zurückgegeben. Der Setter ist leer.

Aus der Dokumentation verstehe ich, dass, wenn der Typ wäre ein boolescher, die "ist" -Methode hat Vorrang vor get, aber der Typ ist String, so ist es nicht sinnvoll, sogar nach einem "is-xxx " Methode?

public class Test { 
    public class Arguments { 
     private String test = Boolean.toString(true); 

     public boolean isTest() { 
      return Boolean.parseBoolean(test); 
     } 

     public String getTest() { 
      return test; 
     } 

     public void setTest(String test) { 
      this.test = test; 
     } 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws IntrospectionException { 
     BeanInfo info = Introspector.getBeanInfo(Arguments.class); 
     System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod()); 
     System.out.println("Setter: " + info.getPropertyDescriptors()[1].getWriteMethod()); 
     PropertyDescriptor descr = new PropertyDescriptor("test", Arguments.class); 
     System.out.println("T"); 
    } 

} 

Gibt es jemanden, der einen Einblick hat?

Zusätzliche Informationen:

  1. Die Reihenfolge das Ergebnis nicht ändert. Die isTest() -Methode wird immer als readMethod betrachtet.
  2. Wenn ich die isTest() einfach in bsTest() umbenenne, werden Getter und Setter als readMethod und writeMethod ausgewählt. Es hat also etwas mit "is-xxx" zu tun.
+0

Was passiert, wenn Sie am Ende der Klasse die Methode 'isTest' deklarieren? Es kann sein, dass es als boolescher Wert erkannt wird, da dies das erste Vorkommen ist und daher der Setter nicht mit dem Typ String übereinstimmt. –

+0

Nein, es macht keinen Sinn, aber anscheinend haben sie sich entschieden (oder es ist ein Fehler). Sie können nicht viel dagegen tun, außer zu stoppen, um Booleans mit Strings darzustellen: D – Dici

+0

Ich habe einige weitere Informationen im ursprünglichen Text hinzugefügt. Die Reihenfolge hat keinen Einfluss auf das Ergebnis. – Quirexx

Antwort

4

Das Ergebnis, das Sie erhalten, ist tatsächlich das erwartete Ergebnis, gemäß der JavaBeans specification.

Zitiert Absatz 8.3.1 für einfache Eigenschaften:

Wenn wir ein passendes Paar von get<PropertyName> und set<PropertyName> Methoden , die nehmen und geben den gleichen Typ zu entdecken, dann sehen wir diese Methoden als Definition einer Lese-Schreib Eigenschaft, deren Name <propertyName> lautet.

Dann zitierte Absatz 8.3.2 für boolean Eigenschaften:

Dieses is<PropertyName> Verfahren kann anstelle eines get<PropertyName> Verfahren zur Verfügung gestellt werden, oder es kann zusätzlich zu einem get<PropertyName> Verfahren bereitgestellt werden.

Wenn die is<PropertyName>-Methode für eine boolesche Eigenschaft vorhanden ist, verwenden wir in beiden Fällen die is<PropertyName>-Methode, um den Eigenschaftswert zu lesen.

Von Ihrem Beispiel ist die Introspector Erfassung sowohl die isTest und getTest Methode. Da isTest Vorrang vor getTest hat, verwendet es isTest, um den Typ der test Eigenschaft als boolean zu bestimmen. Aber dann erwartet der Introspector, dass der Setter die Signatur void setTest(boolean test) hat und er findet sie nicht, daher ist die Setter-Methode null.

Zu beachten ist, dass der Introspector die Felder nicht liest. Es verwendet die Signatur der Getter/Setter-Methoden, um zu bestimmen, welche Felder vorhanden sind und welche Typen sie haben. isTest Methodensignatur gibt für eine Eigenschaft mit dem Namen test vom Typ boolean an. Daher berücksichtigt der Introspector unabhängig vom tatsächlichen Typ test, dass Ihre Klasse eine Eigenschaft aufweist.

In der Tat, für alle Introspecter betroffen ist, die Eigenschaft test möglicherweise nicht einmal existieren! Mit dem folgenden Code können Sie sich davon überzeugen:

class Test { 

    public class Arguments { 
     public boolean isTest() { 
      return true; 
     } 
    } 

    public static void main(String[] args) throws IntrospectionException { 
     BeanInfo info = Introspector.getBeanInfo(Arguments.class); 
     System.out.println("Getter: " + info.getPropertyDescriptors()[1].getReadMethod()); 
     System.out.println("Name of property: " + info.getPropertyDescriptors()[1].getName()); 
    } 

} 
+0

Ich stimme Tunaki zu, und wenn Sie einige Metaprogrammierung tun, können Sie es zwingen, mit einigen Parametern wie gewünscht zu arbeiten: 'PropertyDescriptor descr = neuer PropertyDescriptor (" test ", Arguments.class," getTest "," setTest ") ; ' –

+0

Sie erwähnen" es verwendet isTest, um den Typ der Testeigenschaft als boolean zu bestimmen ", aber die Art des Tests ist eindeutig als String definiert. Oder definiert es den Typ als Boolean, weil der Rückgabewert der Methode Boolean ist? – Quirexx

+0

@Quirexx Der Introspector liest die Felder nicht. Es verwendet die Signatur der Getter/Setter-Methode, um zu bestimmen, welche Felder vorhanden sind und welche entsprechenden Typen vorhanden sind. 'isTest'-Signatur spezifiziert für eine Eigenschaft namens" test "vom Typ boolean, unabhängig vom tatsächlichen Typ von" test " – Tunaki

2

Das eigentliche Mitglied ist für die Introspector völlig irrelevant. Sie können zum Beispiel eine getName() Methode haben, die nur einen festen String zurückgibt und der Introspector findet sie als Getter für ein Mitglied namens "name". Sie können sogar einen Setter haben, wenn das Mitglied nicht existiert. Sie können sogar eine Schnittstelle zu der Introspector geben und es wird die Eigenschaften davon bestimmen, auch wenn es keine echten Mitglieder geben kann.

Mit anderen Worten, die Eigenschaften werden durch die Existenz von Getter-und Setter-Methoden bestimmt und nicht durch die tatsächliche Suche nach Variablen.