Short Story -- Missing Piece
private <T extends SomeClass> void someFunction(SomeClass<T> instance) throws IllegalAccessException {
for (Field field : this.getClass().getDeclaredFields()) {
Object obj = field.get(this);
Class<?> objClass = obj.getClass();
if (objClass.isInstance(instance))
doSomething(instance, (T) obj);
}
- Where we get and store the Class from the Object, then check that against the instance we want to match with.
- We use the wildcard
?
to signify an unknown Type, which saves us from having to figure out, or specify types.
- Then we assure the
doSomething
Method accepts the same generic type argument to allow for similar work
- Therefore we only need to cast to T
As a Whole, With A Working Example of Animals
(Yes this is a reduction :))
Animal Class as a Base
public abstract class Animal {
protected Object color;
protected Animal(Object color) {
this.color = color;
}
protected Animal() {}
}
Various Colors of Animal (To Simplify)
No Color Animal (A Ghost?!)
public class NoColorAnimal extends Animal {
// A null color
public NoColorAnimal() {}
}
A Single Color Animal
public class SingleColorAnimal extends Animal {
// A single String of color
public SingleColorAnimal(String color) {
super(color);
}
}
A Multi-colored Animal
public class MultiColorAnimal extends Animal {
// An Array of colors
public MultiColorAnimal(String... colors) {
super(colors);
}
}
A Zoo With Viewable Animals as Your Enclosing Class
public class ZooAnimals {
public MultiColorAnimal tiger = new MultiColorAnimal("black", "orange");
public SingleColorAnimal dolphin = new SingleColorAnimal("grey");
public <T extends Animal> void viewAnimalIfPresent(Animal<T> animal) throws IllegalAccessException {
for (Field field : this.getClass().getDeclaredFields()) {
Object obj = field.get(this);
Class<?> objClass = obj.getClass();
if (objClass.isInstance(animal))
view(animal, (T) obj, field.getName());
}
}
private <T extends Animal> void view(Animal<T> animal, T obj, String name) {
// TODO - Do something useful with these, but simply log them for now :)
System.out.printf("Viewed a %s; the %s%n", obj.getClass().getSimpleName(), name);
}
}
A Simple Test
ZooAnimals zoo = new ZooAnimals();
@Test
public void test() throws IllegalAccessException {
zoo.viewAnimalIfPresent(zoo.tiger);
zoo.viewAnimalIfPresent(zoo.dolphin);
zoo.viewAnimalIfPresent(new NoColorAnimal());
}
Result of Test
The Console Ouput for Test Showing Proper Type Shifting
Viewed a MultiColorAnimal; the tiger
Viewed a SingleColorAnimal; the dolphin
Where no field matched a colorless Animal, and therefore nothing was printed.