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

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

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

public class Pet {}

public class Dog extends Pet{}

public class Cat extends Pet{}

public class Pug extends Dog{}

public class Manx extends 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(InstantiationException e){

  throw new RuntimeException(e);

  }catch(IllegalAccessException e){

  //此异常表示默认构造器是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 ForNameCreator extends 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(ClassNotFoundException e){

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 LiteralPetCreator extends 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,通过这种方式,你可以询问,有多少个猫对象?我们可以用instanceof对Pet进行计数.

public class PetCount {

//定义一个计数器

static class PetCounter extends HashMap<String ,Integer>{

public void count(String type){

Integer quantity=get(type);

if(quantity!=null){

put(type,quantity+1);

}else{

put(type,1);

}

}

}



/**

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

 * @param creator 宠物创建器

 */

public static void countPets(PetCreator creator){

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(Object obj){

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值