Korrekten Typ für Wert eines Attributs angeben

Für jedes CER-Element AttributeValue gibt es eine Methode specifyValue, damit der Wert des Attributs angegeben (statt berechnet) werden kann. Die Methode verwendet einen beliebigen Wert1 als Eingabe, aber wenn Sie den falschen Typ für den Wert angeben, gibt CER einen Laufzeitfehler aus:

public void incorrectValueType() {

    final FlexibleRetirementYear flexibleRetirementYear =
        FlexibleRetirementYear_Factory.getFactory().newInstance(
            session);

    /**
     * Will not work - retirementCause() expects a String, not a
     * Number.
     *
     * CER will report the message: Attempt to set the value '123'
     * (of type 'java.lang.Integer') on attribute 'retirementCause'
     * of rule class 'FlexibleRetirementYear' (which expects a
     * 'java.lang.String').
     */
    flexibleRetirementYear.retirementCause().specifyValue(123);

  }
1 Technische Benutzer fragen sich an dieser Stelle möglicherweise, warum AttributeValue.specifyValue nicht die generischen Angaben von Java 5 verwendet, um den Wertetyp einzuschränken, der empfangen werden kann.

Falls Regelklasse A die Regelklasse B erweitert, kann die Klasse A jederzeit die Ableitung jedes Attributs der Klasse B überschreiben. Die Klasse A kann ebenfalls jedes Attribut der Klasse B mit einem restriktiveren Typ neu deklarieren (die Deklaration der Klasse A gibt also ihren Typ als Untertyp des von der Klasse B deklarierten Typs an).

Die generierte Java-Schnittstelle für die Klasse A erweitert die generierte Java-Schnittstelle für die Klasse B. Da die Accessoren Berechnungsfunktionen und nicht den Wertetyp direkt zurückgeben, müssen alle Schnittstellen Platzhalterausdrücke verwenden, damit der Compiler zulässt, dass die Deklaration der Klasse A für den Accessor des Attributs die Deklaration der Klasse B erweitert. Aufgrund der Verwendung einer Platzhaltererweiterung kann specifyValue nicht auf einen Typ beschränkt werden und muss daher für den Empfang eines beliebigen Elements Object deklariert werden.

Falls in einem anderen Fall die Java-Klasse C zur Erweiterung der Java-Klasse D eingesetzt werden soll, kann die Klasse C einen restriktiveren Typ für einen der Getter der Klasse D definieren, jedoch nicht die Setter der Klasse D auf einen Subtyp beschränken. Die Klasse C muss den Setter von D implementieren und alle nicht erwünschten Werte während der Laufzeit feststellen (auch wenn dies wohl das Liskovsche Substitutionsprinzip verletzen könnte).

Eine weitere Begründung ist die Tatsache, dass beim Einsatz von rein dynamischen Regelobjekten (d. h. in einer interpretierten Sitzung) keine Beschränkung von Werten zur Kompilierzeit möglich ist.

CER verwendt daher seine Kenntnisse über deklarierte Attributtypen, um falsche Werte zur Laufzeit und nicht zur Kompilierzeit festzustellen.