mardi 29 septembre 2015

Java: Reflection, Generic Types, and Unchecked Casts

My class will be given an Object class. I am then using reflection to iterate over the declared fields of that class and registering a ChangeListener on each field with the Property base class.

The original 'createChangeListener' method looked like this:

private void createChangeListener(Property property) {
    property.addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {                        
            Foo.this.propertyChanged(observable);
        }
    });
}

However, this was producing an unwanted warning:

warning: [unchecked] unchecked call to addListener(ChangeListener<? super T>) as a member of the raw type ObservableValue
    property.addListener(new ChangeListener() {
        where T is a type-variable:
    T extends Object declared in interface ObservableValue

Not to be dissuaded, I provided a generic type for my Property parameter and ChangeListener:

private void createChangeListener(Property<Object> property) {
    property.addListener(new ChangeListener<Object>() {
        @Override
        public void changed(ObservableValue observable, Object oldValue, Object newValue) {                        
            Foo.this.propertyChanged(observable);
        }
    });
}

...Only now to be notified that I have simply shifted my problem to the source of the reflection. The code, below, is now modified to cast to Property<Object> from its original Property w/o a generic type:

if (Property.class.isAssignableFrom(field.getType())) {
    createChangeListener((Property<Object>)(field.get(model)));
}

This previously warningless code is now producing the head-tilting:

warning: [unchecked] unchecked cast
    createChangeListener((Property<Object>)(field.get(model)));
required: Property<Object>
found:    Object

Questions:

  • ಠ_ಠ
  • Given Java's type erasure limitations, what techniques are available to me to safely resolve these warnings?
  • Am I safe to suppress the unchecked warning in the original, non-typed method?




Aucun commentaire:

Enregistrer un commentaire