Class进阶(包含instanceof,Class.isAssignableFrom用法)

来源:互联网 发布:大数据 涂子沛 txt 编辑:程序博客网 时间:2024/06/17 13:03

Class进阶(包含instanceof,Class.isAssignableFrom用法)

首先先定义五个类,继承关系如下:

public class Pet {

 

}

public class Dogextends Pet{

 

}

public class Catextends Pet{

 

}

public class Pugextends Dog{

 

}

public class Manxextends Cat{

 

}

一:创建一个抽象类作为宠物生成器,然后分别用Classs.forName().class字面常量两种方式实现该抽象类.

public abstract class PetCreator {

Random rand=new Random(47);

public abstract List<Class< ?extends Pet>> types();

/**

 * 随机创建一个宠物

 * @return

 */

public Pet randomPet(){

int n=rand.nextInt(types().size());

try{

//其中types()获得类型被指定为'任何从Pet导出的类',因此newInstance()不需要转型就可以产生Pet

return types().get(n).newInstance();

}catch(InstantiationExceptione){

throw new RuntimeException(e);

}catch(IllegalAccessExceptione){

//此异常表示默认构造器是private的情况

throw new RuntimeException(e);

}

}

/**

 * 创建一个宠物数组

 * @param size

 * @return

 */

public Pet[] createArray(int size){

Pet[] result=new Pet[size];

for(int i=0;i<size;i++){

//createArray使用randomPet()来填充数组。

result[i]=randomPet();

}

return result;

}

/**

 * 创建宠物集合

 * @param size

 * @return

 */

public ArrayList<Pet> arrayList(int size){

ArrayList<Pet> result=new ArrayList<Pet>();

//arrayList则是用createArray()来填充

Collections.addAll(result, createArray(size));

return result;

}

 

}

1)用class.forname()来创建一个具体的宠物生成器。

loader方法用Class.forName();方法创建了Class对象的List,这可能会产生ClassNotFoundException异常,这么做是有意义的,因为你传递的是一个在编译器无法验证的String。

public class ForNameCreatorextends PetCreator{

 

//设置成static共享,在类第一次被加载的时候进行初始化,节约内存,和时间

private static List<Class<?extends Pet>> types=new ArrayList<Class<?extends Pet>>();

private static String[]typeNames={

"com.tkij.chapter14.Class.InstanceofAndIsInstance.Cat",

"com.tkij.chapter14.Class.InstanceofAndIsInstance.Dog",

"com.tkij.chapter14.Class.InstanceofAndIsInstance.Pug",

"com.tkij.chapter14.Class.InstanceofAndIsInstance.Manx"

};

private static void loader(){

try{

for(String name:typeNames){

types.add((Class<? extends Pet>)Class.forName(name));

}

}catch(ClassNotFoundExceptione){

throw new RuntimeException(e);

}

}

//静态代码块,在类初始化的时候执行。

static{loader();}

@Override

public List<Class<? extends Pet>> types() {

// TODO Auto-generated method stub

return types;

}

}

(2).class字面常量来创建一个具体的宠物生成器。这一次,生成的types的代码不需要放在try块内,因为它会在编译期进行检查,因此不会抛出任何异常,这与Class.forName不一样。

public class LiteralPetCreatorextends PetCreator{

 

//unmodifiableList()函数是将list变为不可修改

public static final List<Class< ?extends Pet>> allTypes=Collections.unmodifiableList(Arrays.asList(Pet.class,

Dog.class,Cat.class,Pug.class,Manx.class

));

private static final List<Class<?extends Pet>> types=allTypes.subList(allTypes.indexOf(Dog.class),allTypes.size());

@Override

public List<Class<? extends Pet>> types() {

// TODO Auto-generated method stub

return types;

}

public static void main(String[]args) {

System.out.println(types);

}

 

}

二:创建计数器,利用宠物生成器生成宠物集合,然后测试,每种宠物的数量,下面也有两种计数器,第一种使用instanceof实现的。第二种使用Class.isAssignableFrom()实现的递归计数.

(1)为了对Pet进行计数,我们还需要一个计数器能保存不同类型的Pet的数量的工具。Map是次需求的首选,其中键是宠物名,而值是保存Pet数量的Integer,通过这种方式,你可以询问,有多少个猫对象?我们可以用instanceofPet进行计数.

public class PetCount {

//定义一个计数器

static class PetCounter extends HashMap<String ,Integer>{

public void count(Stringtype){

Integer quantity=get(type);

if(quantity!=null){

put(type,quantity+1);

}else{

put(type,1);

}

}

}

/**

 * 对随机生成的宠物进行归类计数

 * @param creator 宠物创建器

 */

public static void countPets(PetCreatorcreator){

PetCounter counter=new PetCounter();

List<Pet> pets=creator.arrayList(20);

for(Pet pet:pets){

if(pet instanceof Pet){

counter.count("Pet");

}

if(pet instanceof Dog){

counter.count("Dog");

}

if(pet instanceof Cat){

counter.count("Cat");

}

if(pet instanceof Pug){

counter.count("Pug");

}

if(pet instanceof Manx){

counter.count("Manx");

}

}

System.out.println(counter);

}

public static void main(String[]args) {

System.out.println("ForNameCreator生成的随机宠物!");

countPets(new ForNameCreator());

System.out.println("LiteralPetCreator生成的随机宠物!");

countPets(new LiteralPetCreator());

}

}

(2)Class.isAssignableFrom()实现递归计数

public class TypeCounter extends HashMap<Class<?>,Integer>{

private Class<?> baseType;

public TypeCounter(Class<?>baseType){

this.baseType=baseType;

}

public void count(Objectobj){

Class<?> type=obj.getClass();

if(!baseType.isAssignableFrom(type)){

throw new RuntimeException(obj+"incorrect type"+type+",should be type or subtype of"+baseType);

}

countClass(type);

}

private void countClass(Class<?>type){

Integer quality=get(type);

put(type,quality==null?1:quality+1);

Class<?> superClass=type.getSuperclass();

if(superClass!=null&&baseType.isAssignableFrom(superClass)){

countClass(superClass);//递归计数

}

}

public String toString(){

StringBuilder result=new StringBuilder("{");

for(Map.Entry<Class<?>,Integer>pair :entrySet()){

result.append(pair.getKey().getSimpleName());

result.append("=");

result.append(pair.getValue());

result.append(",");

}

result.delete(result.length()-1,result.length());

result.append("}");

return result.toString();

}

public static void main(String[]args) {

TypeCounter counter=new TypeCounter(Pet.class);

PetCreator pc=new LiteralPetCreator();

for(Pet pet:pc.arrayList(20)){

counter.count(pet);

}

System.out.println(counter);

}

 

}

阅读全文
1 0
原创粉丝点击