- In C++, the classic cast "(Shape)" does not perform RTTI (Runtime type information, discovers and uses type information while a program is running). It simply tells the compiler to treat the object as the new type.
- In Java, which does perform the type check, this cast is often called a "type-safe downcast." The reason for the term "downcast" is the historical arragement of the class hierarchy diagram.
- There's a third form of RTTI in Java(The first two are upcast and downcast). This is the keyword instanceof, which tells us if an object is an instance of a particular type. It returns a boolean so you use it in the form of a question, like this
if(x instanceof Dog)
((Dog)x).bark();
// typeinfo/pets/Individual.java
// typeinfo/pets/Individual.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
import java.util.*;
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() {}
@Override
public String toString() {
return getClass().getSimpleName() + (name == null ? "" : " " + name);
}
public long id() {
return id;
}
@Override
public boolean equals(Object o) {
return o instanceof Individual && Objects.equals(id, ((Individual) o).id);
}
@Override
public int hashCode() {
return Objects.hash(name, id);
}
@Override
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/Person.java
// typeinfo/pets/Person.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Person extends Individual {
public Person(String name) {
super(name);
}
}
// typeinfo/pets/Pet.java
// typeinfo/pets/Pet.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Pet extends Individual {
public Pet(String name) {
super(name);
}
public Pet() {
super();
}
}
// typeinfo/pets/Dog.java
// typeinfo/pets/Dog.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Dog extends Pet {
public Dog(String name) {
super(name);
}
public Dog() {
super();
}
}
// typeinfo/pets/Mutt.java
// typeinfo/pets/Mutt.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Mutt extends Dog {
public Mutt(String name) {
super(name);
}
public Mutt() {
super();
}
}
// typeinfo/pets/Pug.java
// typeinfo/pets/Pug.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Pug extends Dog {
public Pug(String name) {
super(name);
}
public Pug() {
super();
}
}
// typeinfo/pets/Cat.java
// typeinfo/pets/Cat.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Cat extends Pet {
public Cat(String name) {
super(name);
}
public Cat() {
super();
}
}
// typeinfo/pets/EgyptianMau.java
// typeinfo/pets/EgyptianMau.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class EgyptianMau extends Cat {
public EgyptianMau(String name) {
super(name);
}
public EgyptianMau() {
super();
}
}
// typeinfo/pets/Manx.java
// typeinfo/pets/Manx.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Manx extends Cat {
public Manx(String name) {
super(name);
}
public Manx() {
super();
}
}
// typeinfo/pets/Cymric.java
// typeinfo/pets/Cymric.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Cymric extends Manx {
public Cymric(String name) {
super(name);
}
public Cymric() {
super();
}
}
// typeinfo/pets/Rodent.java
// typeinfo/pets/Rodent.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Rodent extends Pet {
public Rodent(String name) {
super(name);
}
public Rodent() {
super();
}
}
// typeinfo/pets/Rat.java
// typeinfo/pets/Rat.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Rat extends Rodent {
public Rat(String name) {
super(name);
}
public Rat() {
super();
}
}
// typeinfo/pets/Mouse.java
// typeinfo/pets/Mouse.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Mouse extends Rodent {
public Mouse(String name) {
super(name);
}
public Mouse() {
super();
}
}
// typeinfo/pets/Hamster.java
// typeinfo/pets/Hamster.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
public class Hamster extends Rodent {
public Hamster(String name) {
super(name);
}
public Hamster() {
super();
}
}
// typeinfo/pets/PetCreator.java
// typeinfo/pets/PetCreator.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Creates random sequences of Pets
package typeinfo.pets;
import java.util.*;
import java.util.function.*;
public abstract class PetCreator implements Supplier<Pet> {
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 get() { // Create one random Pet
int n = rand.nextInt(types().size());
try {
return types().get(n).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
// typeinfo/pets/ForNameCreator.java
// typeinfo/pets/ForNameCreator.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package typeinfo.pets;
import java.util.*;
public class ForNameCreator extends PetCreator {
private static List<Class<? extends Pet>> types = new ArrayList<>();
// Types you want randomly created:
private static String[] typeNames = {
"typeinfo.pets.Mutt",
"typeinfo.pets.Pug",
"typeinfo.pets.EgyptianMau",
"typeinfo.pets.Manx",
"typeinfo.pets.Cymric",
"typeinfo.pets.Rat",
"typeinfo.pets.Mouse",
"typeinfo.pets.Hamster"
};
@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();
}
@Override
public List<Class<? extends Pet>> types() {
return types;
}
}
// typeinfo/PetCount.java
// typeinfo/PetCount.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Using instanceof
import java.util.*;
import typeinfo.pets.*;
public class PetCount {
static class Counter 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) {
Counter counter = new Counter();
for (Pet pet : Pets.array(20)) {
// List each individual pet:
System.out.print(pet.getClass().getSimpleName() + " ");
if (pet instanceof Pet) {
counter.count("Pet");
}
if (pet instanceof Dog) {
counter.count("Dog");
}
if (pet instanceof Mutt) {
counter.count("Mutt");
}
if (pet instanceof Pug) {
counter.count("Pug");
}
if (pet instanceof Cat) {
counter.count("Cat");
}
if (pet instanceof EgyptianMau) {
counter.count("EgyptianMau");
}
if (pet instanceof Manx) {
counter.count("Manx");
}
if (pet instanceof Cymric) {
counter.count("Cymric");
}
if (pet instanceof Rodent) {
counter.count("Rodent");
}
if (pet instanceof Rat) {
counter.count("Rat");
}
if (pet instanceof Mouse) {
counter.count("Mouse");
}
if (pet instanceof Hamster) {
counter.count("Hamster");
}
}
// Show the counts:
System.out.println();
System.out.println(counter);
}
public static void main(String[] args) {
countPets(new ForNameCreator());
}
}
/* Output:
Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug Mouse Cymric
{EgyptianMau=2, Pug=3, Rat=2, Cymric=5, Mouse=2, Cat=9, Manx=7, Rodent=5, Mutt=3, Dog=6, Pet=20, Hamster=1}
*/
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Individual.java
3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Person.java
4. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Pet.java
5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Dog.java
6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Mutt.java
7. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Pug.java
8. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Cat.java
9. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/EgyptianMau.java
10. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Manx.java
11. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Cymric.java
12. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Rodent.java
13. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Rat.java
14. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Mouse.java
15. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/Hamster.java
16. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/PetCreator.java
17. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/ForNameCreator.java
18. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/typeinfo/pets/PetCount.java