, . , -, getAnimalClass()
- ( , ).
canFeed(animal)
Feeder
( getAnimalClass()
). , Feeder
, .
, Feeder, , Class
, ( getAnimalClass()
, , , ):
final Class<T> typeParameterClass;
public Feeder(Class<T> typeParameterClass){
typeParameterClass = typeParameterClass;
}
canFeed
:
public boolean canFeed(Animal animal) {
return typeParameterClass.isAssignableFrom(animal.getClass());
}
PetStore
:
private Feeder feederFor(Animal animal) {
return feeders.stream()
.filter(feeder -> feeder.canFeed(animal))
.findFirst()
.orElse((Feeder) unknownAnimal -> {});
}
, . , , , , Spring beans, .
, PetStore
Map
:
@Autowired
Map<String, Feeder<? extends Animal>> feederMap;
, ( ) . canFeed
:
private boolean canFeed(String feederName, Animal animal) {
return feederName.contains(animal.getClass().getTypeName());
}
Feeder
:
private Feeder feederFor(Animal animal) {
return feederMap.entrySet().stream()
.filter(entry -> canFeed(entry.getKey(), animal))
.map(Map.Entry::getValue)
.findFirst()
.orElse((Feeder) unknownAnimal -> {});
}
, , - . , canFeed
default
Feeder<T>
:
default <A extends Animal> boolean canFeed(A animalToFeed) {
return A == T;
}
, A == T, - A T. , , . Spring, Java:
this.entityBeanType = ((Class) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]);
Feeder Feeder<T>
, , . , , ( , invokedynamic
), .
, , , . , , , , , , :
, , , , SAM- SAM. , 3% . , / factory, , .
factory, , .
, - . Spring GenericTypeResolver
Animal
, , -.
, LambdaMetafactory . , Config
. ASM , . , , , , Unsafe.defineAnonymousClass
. , Class.getConstantPool
, ASM , JDK. ( ) , , TypeTools. , , Serialization
. , Spring api.
, , (, ), Feeder
-hack hack :
default <A extends Animal> boolean canFeed(A animalToFeed) {
Class<?> feederType = TypeResolver.resolveRawArgument(Feeder.class, this.getClass());
return feederType.isAssignableFrom(animalToFeed.getClass());
}
PetStore
:
@Autowired
private List<Feeder<? extends Animal>> feeders;
public void feed(Animal animal) {
feederFor(animal).feed(animal);
}
private Feeder feederFor(Animal animal) {
return feeders.stream()
.filter(feeder -> feeder.canFeed(animal))
.findFirst()
.orElse(unknownAnimal -> {});
}
, , , , , , (, , ) .