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,通过这种方式,你可以询问,有多少个猫对象?我们可以用instanceof对Pet进行计数.
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);
}
}
- Class进阶(包含instanceof,Class.isAssignableFrom用法)
- class.isAssignableFrom 和 instanceof
- Class.isAssignableFrom与 instanceof 区别
- Class.isAssignableFrom与 instanceof 区别
- Class.isAssignableFrom()和instanceOf关键字
- Class isAssignableFrom与instanceof区别
- Class.isAssignableFrom与 instanceof 区别
- Class.isAssignableFrom与 instanceof 区别
- class.isassignablefrom(class clz)方法 与 instanceof
- class.isassignablefrom(class clz)方法 与 instanceof
- class.isassignablefrom(class clz)方法 与 instanceof
- 【Java基础】Class.isAssignableFrom与 instanceof 区别
- [javase]class.isassignablefrom(class clz)方法 与 instanceof
- Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
- Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
- Class.isAssignableFrom(Class c)与instanceof关键字有何区别
- Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
- Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
- kotlin官方文档中文翻译(二) 基础内容
- MapReduce学习(1)
- 【loj】#6008. 「网络流 24 题」餐巾计划(最小费用流)
- 守护进程的实现以及fork两次的原因
- centos安装libacl-devel
- Class进阶(包含instanceof,Class.isAssignableFrom用法)
- 经典排序例题
- 零基础学小程序006(后台数据的获取与解析)----请求服务器json数据展现到小程序上
- linux module
- Hawk-and-Chicken
- Gradle's dependency cache may be corrupt解决方法
- 让你明白response.sendRedirect()与request.getRequestDispatcher().forward()区别
- JS概念理解(四)——闭包
- html5学习历程1