`

14章类型信息-之类型转换前先做检查--之使用类字面常量--类名.class--以及动态instanceof(isInstance方法)----递归计数(计算各个类的个数)

 
阅读更多

实例代码:

实体类父类:

//: typeinfo/pets/Individual.java
package typeinfo.pets;


public class Individual implements Comparable<Individual> {
private static long counter = 0;
private final long id = counter++;
private String name;
public Individual(String name) { this.name = name; }
// 'name' is optional:
public Individual() {}
public String toString() {
return getClass().getSimpleName() +
(name == null ? "" : " " + name);
}
public long id() { return id; }
public boolean equals(Object o) {
return o instanceof Individual &&
id == ((Individual)o).id;
}
public int hashCode() {
int result = 17;
if(name != null)
result = 37 * result + name.hashCode();
result = 37 * result + (int)id;
return result;
}
public int compareTo(Individual arg) {
// Compare by class name first:
String first = getClass().getSimpleName();
String argFirst = arg.getClass().getSimpleName();
int firstCompare = first.compareTo(argFirst);
if(firstCompare != 0)
return firstCompare;
if(name != null && arg.name != null) {
int secondCompare = name.compareTo(arg.name);
if(secondCompare != 0)
return secondCompare;
}
return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));
}
} ///:~

继承类:

//: typeinfo/pets/Cat.java
package typeinfo.pets;


public class Cat extends Pet {
public Cat(String name) { super(name); }
public Cat() { super(); }
} ///:~

 

//: typeinfo/pets/Dog.java
package typeinfo.pets;


public class Dog extends Pet {
public Dog(String name) { super(name); }
public Dog() { super(); }
} ///:~

 

//: typeinfo/pets/Rodent.java
package typeinfo.pets;


public class Rodent extends Pet {
public Rodent(String name) { super(name); }
public Rodent() { super(); }
} ///:~

创建宠物的抽象类:

//: typeinfo/pets/PetCreator.java
// Creates random sequences of Pets.
package typeinfo.pets;
import java.util.*;


public abstract class PetCreator {
private Random rand = new Random(47);
// The List of the different types of Pet to create:
public abstract List<Class<? extends Pet>> types();
public Pet randomPet() { // Create one random Pet
int n = rand.nextInt(types().size());
try {
return types().get(n).newInstance();
} catch(InstantiationException e) {
throw new RuntimeException(e);
} catch(IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public Pet[] createArray(int size) {
Pet[] result = new Pet[size];
for(int i = 0; i < size; i++)
result[i] = randomPet();
return result;
}
public ArrayList<Pet> arrayList(int size) {
ArrayList<Pet> result = new ArrayList<Pet>();
Collections.addAll(result, createArray(size));
return result;
}
} ///:~

实现(创建宠物抽象类)的实现类:

//: typeinfo/pets/LiteralPetCreator.java
// Using class literals.
package typeinfo.pets;
import java.util.*;


public class LiteralPetCreator extends PetCreator {
// No try block needed.
@SuppressWarnings("unchecked")
public static final List<Class<? extends Pet>> types =
Collections.unmodifiableList(Arrays.asList(
Dog.class, Cat.class, Rodent.class));
//这里的Collections.unmodifiableList是指

//返回指定列表的不可修改视图。此方法允许模块为用户提供对内部列表的“只读”访问
public List<Class<? extends Pet>> types() {
return types;
}
}

为了将LiteralPetCreator作为默认实现,创建一个使用了LiteralPetCreator的外观类:

//: typeinfo/pets/Pets.java
// Facade to produce a default PetCreator.
package typeinfo.pets;
import java.util.*;


public class Pets {
public static final PetCreator creator =
new LiteralPetCreator();
public static Pet randomPet() {
return creator.randomPet();
}
public static Pet[] createArray(int size) {
return creator.createArray(size);
}
public static ArrayList<Pet> arrayList(int size) {
return creator.arrayList(size);
}
} ///:~

用于计算各个宠物个数的类:

package typeinfo.pets;


//: typeinfo/PetCount.java
// Using instanceof.
import typeinfo.pets.*;
import java.util.*;
import static net.mindview.util.Print.*;


public class PetCount {
static class PetCounter extends HashMap<String,Integer> {
public void count(String type) {
Integer quantity = get(type);
if(quantity == null)
put(type, 1);
else
put(type, quantity + 1);
}
}
public static void countPets(PetCreator creator) {
PetCounter counter= new PetCounter();
for(Pet pet : creator.createArray(20)) {
// List each individual pet:
printnb(pet.getClass().getSimpleName() + " ");
if(pet instanceof Pet)
counter.count("Pet");
if(pet instanceof Dog)
counter.count("Dog");
if(pet instanceof Cat)
counter.count("Cat");
if(pet instanceof Rodent)
counter.count("Rodent");
}
// Show the counts:
print();
print(counter);
}
}

测试类:

package typeinfo.pets;


//: typeinfo/PetCount2.java
import typeinfo.pets.*;


public class PetCount2 {
public static void main(String[] args) {
PetCount.countPets(Pets.creator);
}
} /* (Execute to see output) *///:~

//测试打印:Rodent Rodent Dog Rodent Dog Rodent Dog Rodent Cat Dog Cat Cat Cat Dog Rodent Dog Dog Dog Rodent Dog
//{Cat=4, Pet=20, Dog=9, Rodent=7}

工具类:

//: net/mindview/util/Print.java
// Print methods that can be used without
// qualifiers, using Java SE5 static imports:
package net.mindview.util;
import java.io.*;


public class Print {
// Print with a newline:
public static void print(Object obj) {
System.out.println(obj);
}
// Print a newline by itself:
public static void print() {
System.out.println();
}
// Print with no line break:
public static void printnb(Object obj) {
System.out.print(obj);
}
// The new Java SE5 printf() (from C):
public static PrintStream
printf(String format, Object... args) {
return System.out.printf(format, args);
}
} ///:~

---------------------动态的instanceof------------------isInstance方法,

-----用到上面的LiteralPetCreator、Pets类-------------------------------

动态计算各个宠物个数的类:

package typeinfo.pets;


//: typeinfo/PetCount3.java
// Using isInstance()
import typeinfo.pets.*;
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;


public class PetCount3 {
static class PetCounter
extends LinkedHashMap<Class<? extends Pet>,Integer> {
public PetCounter() {
super(MapData.map(LiteralPetCreator.types, 0));
}
public void count(Pet pet) {
// Class.isInstance() eliminates instanceofs:
for(Map.Entry<Class<? extends Pet>,Integer> pair
: entrySet())
if(pair.getKey().isInstance(pet))
put(pair.getKey(), pair.getValue() + 1);
}
public String toString() {
StringBuilder result = new StringBuilder("{");
for(Map.Entry<Class<? extends Pet>,Integer> pair
: entrySet()) {
result.append(pair.getKey().getSimpleName());
result.append("=");
result.append(pair.getValue());
result.append(", ");
}
result.delete(result.length()-2, result.length());
result.append("}");
return result.toString();
}
}

//这个是测试结果的main方法

public static void main(String[] args) {
PetCounter petCount = new PetCounter();
for(Pet pet : Pets.createArray(20)) {
printnb(pet.getClass().getSimpleName() + " ");
petCount.count(pet);
}
print();
print(petCount);
}
}

 

//打印结果:Rodent Rodent Cat Rodent Cat Rodent Cat Rodent Dog Cat Dog Dog Dog Cat Rodent Cat Cat Cat Rodent Cat{Dog=4, Cat=9, Rodent=7}

工具类:

1、

//: net/mindview/util/MapData.java
// A Map filled with data using a generator object.
package net.mindview.util;
import java.util.*;


public class MapData<K,V> extends LinkedHashMap<K,V> {
// A single Pair Generator:
public MapData(Generator<Pair<K,V>> gen, int quantity) {
for(int i = 0; i < quantity; i++) {
Pair<K,V> p = gen.next();
put(p.key, p.value);
}
}
// Two separate Generators:
public MapData(Generator<K> genK, Generator<V> genV,
int quantity) {
for(int i = 0; i < quantity; i++) {
put(genK.next(), genV.next());
}
}
// A key Generator and a single value:
public MapData(Generator<K> genK, V value, int quantity){
for(int i = 0; i < quantity; i++) {
put(genK.next(), value);
}
}
// An Iterable and a value Generator:
public MapData(Iterable<K> genK, Generator<V> genV) {
for(K key : genK) {
put(key, genV.next());
}
}
// An Iterable and a single value:
public MapData(Iterable<K> genK, V value) {
for(K key : genK) {
put(key, value);
}
}
// Generic convenience methods:
public static <K,V> MapData<K,V>
map(Generator<Pair<K,V>> gen, int quantity) {
return new MapData<K,V>(gen, quantity);
}
public static <K,V> MapData<K,V>
map(Generator<K> genK, Generator<V> genV, int quantity) {
return new MapData<K,V>(genK, genV, quantity);
}
public static <K,V> MapData<K,V>
map(Generator<K> genK, V value, int quantity) {
return new MapData<K,V>(genK, value, quantity);
}
public static <K,V> MapData<K,V>
map(Iterable<K> genK, Generator<V> genV) {
return new MapData<K,V>(genK, genV);
}
public static <K,V> MapData<K,V>
map(Iterable<K> genK, V value) {
return new MapData<K,V>(genK, value);
}
} ///:~

2、

//: net/mindview/util/Generator.java
// A generic interface.
package net.mindview.util;
public interface Generator<T> { T next(); } ///:~

3、

//: net/mindview/util/Pair.java
package net.mindview.util;


public class Pair<K,V> {
public final K key;
public final V value;
public Pair(K k, V v) {
key = k;
value = v;
}
} ///:~

--------------------------------递归计数-----------------------

------------------------不局限于pet的工具类-------------------------

工具类:

//: net/mindview/util/TypeCounter.java
// Counts instances of a type family.
package net.mindview.util;
import java.util.*;


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 quantity = get(type);
put(type, quantity == null ? 1 : quantity + 1);
Class<?> superClass = type.getSuperclass();
if(superClass != null &&
baseType.isAssignableFrom(superClass))//判定此 Class 对象所表示的类或接口与指定的 Class 参数

//所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false
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()-2, result.length());
result.append("}");
return result.toString();
}
} ///:~

测试类:

package typeinfo.pets;


//: typeinfo/PetCount4.java
import typeinfo.pets.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;


public class PetCount4 {
public static void main(String[] args) {
TypeCounter counter = new TypeCounter(Pet.class);
for(Pet pet : Pets.createArray(20)) {
printnb(pet.getClass().getSimpleName() + " ");
counter.count(pet);
}
print();
print(counter);
}
}

打印结果:

//Rodent Rodent Cat Rodent Cat Rodent Cat Rodent Dog Cat Dog Dog Dog Cat Rodent Cat Cat Cat Rodent Cat
{Pet=20, Cat=9, Dog=4, Rodent=7}

分享到:
评论

相关推荐

    cors-filter-1.7.jar 和 java-property-utils-1.9.jar

    在这个例子中,`cors.filter`类是CORSFilter的全限定类名,`cors.allowGenericHttpRequests`参数允许非简单请求,`cors.allowOrigin`参数设置允许的源,星号(*)表示允许所有源。 `java-property-utils-1.9.jar` ...

    class常量池类型分类.pdf

    在Java中,每个`.class`文件都包含一个常量池(Constant Pool),它是一个特殊的数据结构,用于存储类或接口的编译期常量,包括直接引用到其他类、字段和方法的信息。常量池在类加载时被创建,并且在整个程序运行...

    cors-filter-1.7.jar java-util-1.9.1.jar

    这里,`filter-name`是过滤器的标识,`filter-class`是CORSFilter的全限定类名。 3. **定制CORS行为**:你可以在过滤器配置中添加属性来定制CORS的行为,例如: ```xml &lt;init-param&gt; &lt;param-name&gt;cors....

    qt通过类名动态创建对象

    这个系统是Qt框架的一个核心特性,它为C++语言提供了运行时类型信息、信号与槽机制以及动态属性系统。元对象系统的关键组件是`QMetaObject`类,它存储了关于一个类的元数据,如类名、父类名、方法、信号和槽等。 要...

    java元数据——CLass类

    通过这种方式不会初始化静态域,使用 .class 的方式获取Class对象叫做类的字面常量。 Class clazz = Integer.class; Class clazz = int.class; 3. 对于基本数据类型的封装类还可以通过 .TYPE 的方式获取其Class ...

    jd-gui-0.3.5.windows.rar

    Java开发过程中,有时候我们需要查看或理解已编译的.class文件中的源代码,因为这些文件是Java编译器生成的字节码,不包含原始的源代码信息。这时,我们就需要借助像"jd-gui-0.3.5.windows"这样的工具,它是一个流行...

    通过类名获取类的实例对象

    反射允许程序在运行时检查自身结构,包括类、方法和属性等,从而实现动态类型操作。在Java中,反射是通过`Class`类和相关的API来实现的,而在C++中,由于标准库并不直接支持反射,我们需要借助一些第三方库或者...

    commons-lang-2.6jar包

    4. **反射工具**:`ClassUtils`提供了类和类名的处理,包括获取类的加载器、比较类是否相等、转换对象类型等。 5. **枚举处理**:在Java 5引入枚举之前,`EnumUtils`提供了对枚举的支持。 6. **数组操作**:`...

    Node.js-parse-class解析hyperscript类符号

    例如,当服务器接收到一个包含hyperscript的请求时,`parse-class`可以帮助解析其中的类名,并根据这些信息来动态生成或修改DOM结构。 在实际应用中,`parse-class`可以与其他Node.js库如`cheerio`(用于服务器端的...

    mysql-connector-java-5.1.22-bin.jar

    MySQL Connector/J的工作原理基于JDBC规范,它提供了一系列的Java类和接口,这些类和接口与MySQL服务器进行通信,实现了SQL语句的执行、结果集的获取以及事务处理等功能。在Java应用程序中,开发人员通常会通过`...

    PHP强制对象类型之instanceof操作符

    要避免上述问题,我们可以使用`instanceof`操作符在方法内部进行类型检查: ```php abstract class HTMLElement { // ... public function process(HTMLElement $element) { if ($element instanceof Div) { /...

    commons-codec-1.15.jar

    apache提供了一个加密包commons-codec,里面提供了常用的编解码方法。这里提供了commons-codec-1.15.jar文件,供大家使用。

    288.286.JAVA基础教程_面向对象(中)-instanceof关键字的使用(288).rar

    1. **类型转换安全检查**:在进行强制类型转换前,我们通常会先使用`instanceof`检查目标对象是否可以被转换,以避免ClassCastException。例如: ```java if (obj instanceof String) { String str = (String)obj...

    Java 实例 - instanceof 关键字用法源代码-详细教程.zip

    在Java编程语言中,`instanceof`关键字是一个非常重要的概念,它主要用于判断对象是否属于某个类、接口或者其子类。这个关键字可以帮助开发者确定对象的实际类型,从而在运行时进行类型检查,执行条件操作或者执行多...

    查看java class 文件工具dex-tool

    在Java开发领域,深入理解字节码和类文件结构对于优化代码、调试和逆向工程至关重要。`dex-tool`是一个非常实用的工具,它允许开发者查看和操作Android平台上的Dex(Dalvik Executable)文件,这些文件包含了编译后...

    Php-extension-class.zip_php extension _site:www.pudn.com

    2. **创建PHP类定义**:使用`zend_class_entry`定义类的基本信息,如类名、父类、常量和方法。 3. **映射结构体成员为类属性**:使用`zend_declare_property`函数声明类的属性,这些属性对应于C结构体的成员。 4. **...

    class.getMethods()

    每个`Method`对象封装了类的一个方法的所有信息,如方法名、返回类型、参数类型以及修饰符等。这些信息可以通过`Method`对象的各种方法获取,例如: - `getName()`:获取方法名。 - `getReturnType()`:获取方法的...

    Java语言基础入门教程 Java实训教程 4.类构造函数-this-静态属性方法-instanceof运算符共55页.pptx

    本章节主要介绍了Java中类的高级概念,包括构造函数、`this`关键字、静态属性和方法以及`instanceof`运算符等。掌握这些概念有助于开发者更好地理解和运用Java面向对象编程的核心原理和技术。此外,还介绍了包的概念...

    mysql-connector-java-8.0.29.zip

    java连接mysql的稳定驱动

    前端项目-classlist.zip

    在前端开发中,元素的类名管理是一个常见的需求,用于实现动态样式切换、交互效果以及响应式设计。`classlist.zip`文件中的`classList.js-master`项目提供了一个跨浏览器的`Element.classList`实现,旨在解决老旧...

Global site tag (gtag.js) - Google Analytics