14章类型信息-之类型转换前先做检查--之instanceof

instanceof用法:

对于instanceof有比较严格的限制,只可将其与命名类型进行比较,而不能与class对象做比较。

理解:这里所说的就是像if(pet instanceof Mutt)
        counter.count("Mutt");这里的Mutt,不能用对象比较,只能用类名,比如(Mutt mutt = new Mutt()然后用mutt)或者 Mutt.class就不行了,

实例代码:

实体类父类:

//: 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/ForNameCreator.java
package typeinfo.pets;
import java.util.*;

public class ForNameCreator extends PetCreator {

private static List<Class<? extends Pet>> types =
    new ArrayList<Class<? extends Pet>>();
  // Types that you want to be randomly created:
  private static String[] typeNames = {
    "typeinfo.pets.Cat",
    "typeinfo.pets.Dog",
    "typeinfo.pets.Rodent"
  };
  @SuppressWarnings("unchecked")
  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(); }
  public List<Class<? extends Pet>> types() {return types;}
} ///:~

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

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);
  }
  public static void main(String[] args) {
    countPets(new ForNameCreator());
  }
}

//测试打印: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);
  }
} ///:~

时间: 2024-11-04 07:26:39

14章类型信息-之类型转换前先做检查--之instanceof的相关文章

14章类型信息之使用类字面常量

14章类型信息-之类型转换前先做检查--之使用类字面常量--类名.class--以及动态instanceof(isInstance方法)----递归计数(计算各个类的个数) 实例代码: 实体类父类: //: typeinfo/pets/Individual.javapackage typeinfo.pets; public class Individual implements Comparable<Individual> {  private static long counter = 0;

Java编程思想——第14章 类型信息(二)反射

六.反射:运行时的类信息 我们已经知道了,在编译时,编译器必须知道所有要通过RTTI来处理的类.而反射提供了一种机制——用来检查可用的方法,并返回方法名.区别就在于RTTI是处理已知类的,而反射用于处理未知类.Class类与java.lang.reflect类库一起对反射概念进行支持,该类库包含Field.Method以及Constructor(每个类都实现了Member接口).这些类型是由JVM运行时创建的,用来表示未知类种对应的成员.使用Constructor(构造函数)创建新的对象,用ge

14章.类型信息(1)

运行时类型信息使得你可以在程序运行时发现和使用类型信息. java在运行时识别对象和类的信息有两种方式:(1)“传统的”RTTI,它假定我们在编译时已经知道了所有的类型:(2)“反射”机制,它允许我们在运行时发现和使用类的信息. 一.为什么需要RTTI(Run-Time-Type-Information) 面向对象编程的基本目的是:让代码只操纵基类的引用,这样如果要在基类下面添加新类时,不会影响原来的代码. 例如: 图中的动物是基类,位于顶部,派生类向下扩展. 先看一下,如果我们不操纵基类,会有

14章类型信息

1.初始化被延迟到了对静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行 01.static final int staticFinal = 47;这样直接引用class就可以不用初始化,因为这个是编译期常量,这个值不需要对Initable类进行初始化就可以被读取. 02. static final int staticFinal2 =ClassInitialization.rand.nextInt(1000); 这个是不确定的,所以要初始化后,才能引用(对于像这里的stati

Java编程思想读书笔记--第14章类型信息

7.动态代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. 什么是代理模式? 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 代理模式有什么好处? 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉及到的角色有: 抽象角色:声明真实对象和代理对象的共同接口,这样一来在任何可以使用目标对象

java 类型转换前先做检查

1.传统的类型转换由RTTI确保正确性. 2.instanceof关键字(二元操作符) ,返回一个Boolean值,告诉我们对象是不是某个类或该类派生类的实例,他判断的是类型. if (a instanceof A) //对象a是不是属于A类型,A可能是a父类的父类,如果是这样也返回true 3.instanceof 不能比较Class对象,对于Class对象使用isAssignableFrom()判断 if (as.isAssignableFrom(cs))// Class对象cs所在类是不是

C++ Primer学习总结 第14章 操作重载与类型转换

第14章 操作重载与类型转换 1.    可以直接调用重载的运算符函数. 但是如果对于一个运算符比如+号,既有重载的成员函数,又有重载的非成员函数,那么此时如果直接使用+号,那么就会出现错误. 因为编译器不知道要调用那个运算符. 2.     逗号,运算符 逻辑与&&运算符 逻辑或||运算符不建议重载. 因为上述3种运算符本身是有求值顺序和短路求值特性(&&和||有短路求值特性)的. 但是重载后的运算符本质上是一次函数调用, 所以求值顺序和短路求值特性都会消失. 注意上面第

第十四章 类型信息

前言 在开始介绍类型信息之前一定要区分一些概念: 1.静态类型语言与动态类型语言 静态类型语言:在编译期进行类型检查的语言(例如,Java).(例如 int i = 3;) 动态类型语言:在运行期进行类型检查的语言(例如,JavaScript).最明显的特征为变量没有类型值有类型(如,var=3;) 2.类型检查与类型转换(在Java中的区别) 类型检查:发生在编译期,检查方法是不是接收到了合适类型的参数,赋值是不是有合适类型的右值. 类型转换正确性检查:发生在运行期,检查一个类型变换到另外一个

《JAVA编程思想》学习笔记——第十四章 类型信息

运行时类型信息使得你可以在程序运行时发现和使用类型信息. 主要有两种方式:一种是"传统的"RTTI, 它假定我们在编译时已经知道了所有的类型;另一种是"反射"机制,它允许我们在运行时发现和使用类的信息. Class对象 类是程序的一部分,每个类都有一个Class对象.换言之,每当编写并且编译一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名的.class文件中).为了生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为"类