🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### [使用类字面量](https://lingcoder.gitee.io/onjava8/#/book/19-Type-Information?id=%e4%bd%bf%e7%94%a8%e7%b1%bb%e5%ad%97%e9%9d%a2%e9%87%8f) 如果我们使用类字面量重新实现`PetCreator`类的话,其结果在很多方面都会更清晰: ~~~ // typeinfo/pets/LiteralPetCreator.java // 使用类字面量 // {java typeinfo.pets.LiteralPetCreator} package typeinfo.pets; import java.util.*; public class LiteralPetCreator extends PetCreator { // try 代码块不再需要 @SuppressWarnings("unchecked") public static final List<Class<? extends Pet>> ALL_TYPES = Collections.unmodifiableList(Arrays.asList( Pet.class, Dog.class, Cat.class, Rodent.class, Mutt.class, Pug.class, EgyptianMau.class, Manx.class, Cymric.class, Rat.class, Mouse.class, Hamster.class)); // 用于随机创建的类型: private static final List<Class<? extends Pet>> TYPES = ALL_TYPES.subList(ALL_TYPES.indexOf(Mutt.class), ALL_TYPES.size()); @Override public List<Class<? extends Pet>> types() { return TYPES; } public static void main(String[] args) { System.out.println(TYPES); } } ~~~ 输出结果: ~~~ [class typeinfo.pets.Mutt, class typeinfo.pets.Pug, class typeinfo.pets.EgyptianMau, class typeinfo.pets.Manx, class typeinfo.pets.Cymric, class typeinfo.pets.Rat, class typeinfo.pets.Mouse, class typeinfo.pets.Hamster] ~~~ 在即将到来的`PetCount3.java`示例中,我们用所有`Pet`类型预先加载一个`Map`(不仅仅是随机生成的),因此`ALL_TYPES`类型的列表是必要的。`types`列表是`ALL_TYPES`类型(使用`List.subList()`创建)的一部分,它包含精确的宠物类型,因此用于随机生成`Pet`。 这次,`types`的创建没有被`try`块包围,因为它是在编译时计算的,因此不会引发任何异常,不像`Class.forName()`。 我们现在在`typeinfo.pets`库中有两个`PetCreator`的实现。为了提供第二个作为默认实现,我们可以创建一个使用`LiteralPetCreator`的*外观模式*: ~~~ // typeinfo/pets/Pets.java // Facade to produce a default PetCreator package typeinfo.pets; import java.util.*; import java.util.stream.*; public class Pets { public static final PetCreator CREATOR = new LiteralPetCreator(); public static Pet get() { return CREATOR.get(); } public static Pet[] array(int size) { Pet[] result = new Pet[size]; for (int i = 0; i < size; i++) result[i] = CREATOR.get(); return result; } public static List<Pet> list(int size) { List<Pet> result = new ArrayList<>(); Collections.addAll(result, array(size)); return result; } public static Stream<Pet> stream() { return Stream.generate(CREATOR); } } ~~~ 这还提供了对`get()`、`array()`和`list()`的间接调用,以及生成`Stream<Pet>`的新方法。 因为`PetCount.countPets()`采用了`PetCreator`参数,所以我们可以很容易地测试`LiteralPetCreator`(通过上面的外观模式): ~~~ // typeinfo/PetCount2.java import typeinfo.pets.*; public class PetCount2 { public static void main(String[] args) { PetCount.countPets(Pets.CREATOR); } } ~~~ 输出结果: ~~~ Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug Mouse Cymric {EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1} ~~~ 输出与`PetCount.java`的输出相同。