练习1:
// In ToyTest.java, comment out Toy's default constructor and
// explain what happens.
import static net.mindview.util.Print.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
class Toy {
// Comment out the following default constructor
// to see NoSuchMethodError from (*1*)
//Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots {
FancyToy() { super(1); }
}
public class Ja14_1 {
static void printInfo(Class cc) {
print("Class name: " + cc.getName() +
" is interface? [" + cc.isInterface() + "]");
print("Simple name: " + cc.getSimpleName());
print("Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("FancyToy");
} catch(ClassNotFoundException e) {
print("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
for(Class face : c.getInterfaces())
printInfo(face);
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
obj = up.newInstance();
} catch(InstantiationException e) {
print("Cannot instantiate");
System.exit(1);
} catch(IllegalAccessException e) {
print("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());
}
}
练习2:
// Incorporate a new kind of interface into ToyTest.java and
// verify that it is detected and displayed properly.
import static net.mindview.util.Print.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
interface A{}
class Toy {
// Comment out the following default constructor
// to see NoSuchMethodError from (*1*)
Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots,A {
FancyToy() { super(1); }
}
public class Ja14_2 {
static void printInfo(Class cc) {
print("Class name: " + cc.getName() +
" is interface? [" + cc.isInterface() + "]");
print("Simple name: " + cc.getSimpleName());
print("Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("FancyToy");
} catch(ClassNotFoundException e) {
print("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
for(Class face : c.getInterfaces())
printInfo(face);
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
obj = up.newInstance();
} catch(InstantiationException e) {
print("Cannot instantiate");
System.exit(1);
} catch(IllegalAccessException e) {
print("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());
}
}
练习3:
/* Add Rhomboid to Shapes.java. Create a Rhomboid, upcast it to a Shape,
* then downcast it back to a Rhomboid. Try downcasting to a Circle and
* see what happens.'
*/
import polymorphism.shape.*;
import static net.mindview.util.Print.*;
class Rhomboid extends Shape{
public void draw() { print("Rhomboid.draw()"); }
public void erase() { print("Rhomboid.erase()"); }
}
public class Ja14_3 {
private static RandomShapeGenerator gen =
new RandomShapeGenerator(1);
public static void main(String[] args) {
/*Shape[] s = new Shape[9];
// Fill up the array with shapes:
for(int i = 0; i < s.length; i++)
s[i] = gen.next();
// Make polymorphic method calls:
for(Shape shp : s)
shp.draw();*/
Shape a=new Rhomboid();
a.draw();
((Rhomboid)a).draw();
((Circle)a).draw();
}
}
练习4:
/* Modify the previous exercise so that it uses instancof to check the
* type before performing the downcast.
*/
import polymorphism.shape.*;
import static net.mindview.util.Print.*;
class Rhomboid extends Shape{
public void draw() { print("Rhomboid.draw()"); }
public void erase() { print("Rhomboid.erase()"); }
}
public class Ja14_4 {
private static RandomShapeGenerator gen =
new RandomShapeGenerator(1);
public static void main(String[] args) {
/*Shape[] s = new Shape[9];
// Fill up the array with shapes:
for(int i = 0; i < s.length; i++)
s[i] = gen.next();
// Make polymorphic method calls:
for(Shape shp : s)
shp.draw();*/
Shape a=new Rhomboid();
a.draw();
if(a instanceof Rhomboid)((Rhomboid)a).draw();
if(a instanceof Circle)((Circle)a).draw();
}
}
练习5:
/* Implement a rotate(Shape) method in Shapes.java, such that it checks
* to see if it is rotating a Circle (and, if so, doesn't perform the
* operation).
*/
import static net.mindview.util.Print.*;
import java.util.*;
class Shape {
public void draw() {}
public void erase() {}
public void rotate() {}
}
class Square extends Shape {
public void draw() { print("Square.draw()"); }
public void erase() { print("Square.erase()"); }
public void rotate() { print("Square.rotate()"); }
}
class Triangle extends Shape {
public void draw() { print("Triangle.draw()"); }
public void erase() { print("Triangle.erase()"); }
public void rotate() { print("Triangle.rotate()"); }
}
class Circle extends Shape {
public void draw() { print("Circle.draw()"); }
public void erase() { print("Circle.erase()"); }
public void rotate() { print("Circle.rotate()"); }
}
class RandomShapeGenerator {
private Random rand = new Random(47);
public RandomShapeGenerator(){}
public Shape next() {
switch(rand.nextInt(3)) {
default:
case 0: return new Circle();
case 1: return new Square();
case 2: return new Triangle();
}
}
}
public class Ja14_5{
private static RandomShapeGenerator gen =
new RandomShapeGenerator();
public static void main(String[] args){
Shape[] s = new Shape[9];
// Fill up the array with shapes:
for(int i = 0; i < s.length; i++)
s[i] = gen.next();
// Make polymorphic method calls:
for(Shape shp : s){
if(!(shp instanceof Circle))shp.rotate();
}
}
}
练习6:
/* Modify Shapes.java so that it can "highlight" (set a flag in)
* all shapes of a particular type. The toString() method for each
* derived Shape should indicate whether that Shape is "highlighted."
*/
import static net.mindview.util.Print.*;
import java.util.*;
class Shape {
public void draw() {}
public void erase() {}
public void rotate() {}
void flag(){}
}
class Square extends Shape {
public void draw() { print("Square.draw()"); }
public void erase() { print("Square.erase()"); }
public void rotate() { print("Square.rotate()"); }
private static boolean flag=false;
void flag(){flag=true;}
public String toString(){return ("Square: "+flag);}
}
class Triangle extends Shape {
public void draw() { print("Triangle.draw()"); }
public void erase() { print("Triangle.erase()"); }
public void rotate() { print("Triangle.rotate()"); }
private static boolean flag=false;
void flag(){flag=true;}
public String toString(){return ("Triangle: "+flag);}
}
class Circle extends Shape {
public void draw() { print("Circle.draw()"); }
public void erase() { print("Circle.erase()"); }
public void rotate() { print("Circle.rotate()"); }
private static boolean flag=false;
void flag(){flag=true;}
public String toString(){return ("Circle: "+flag);}
}
class RandomShapeGenerator {
private Random rand = new Random(47);
public RandomShapeGenerator(){}
public Shape next() {
switch(rand.nextInt(3)) {
default:
case 0: return new Circle();
case 1: return new Square();
case 2: return new Triangle();
}
}
}
public class Ja14_6{
private static RandomShapeGenerator gen =
new RandomShapeGenerator();
public static void main(String[] args){
Shape[] s = new Shape[9];
// Fill up the array with shapes:
for(int i = 0; i < s.length; i++)
s[i] = gen.next();
// Make polymorphic method calls:
for(Shape shp : s){
if((shp instanceof Circle)) shp.flag();
print(shp);
}
}
}
练习7:
/* Modify SweetShop.java so that each type of object creation is controlled
* by a command-line argument. That is, if your command line is "java
* SweetShop Candy," then only the Candy object is created. Notice how you
* can control which Class object are loaded via the command-line argument.
*/
import static net.mindview.util.Print.*;
class Candy {
static { print("Loading Candy"); }
//void mm(){print("fdaaaa");}
}
class Gum {
static { print("Loading Gum"); }
}
class Cookie {
static { print("Loading Cookie"); }
}
public class Ja14_7 {
public static void main(String[] args) {
if(args.length<1)System.exit(0);
Class c=null;
try{
c=Class.forName(args[0]);
print(c.getName()+" "+c.isInterface());
//c.getClass().mm();
}catch(Exception e){}
/*
print("inside main");
new Candy();
print("After creating Candy");
try {
Class.forName("Gum");
} catch(ClassNotFoundException e) {
print("Couldn't find Gum");
}
print("After Class.forName(\"Gum\")");
new Cookie();
print("After creating Cookie");*/
}
}
练习8:
// Write a method that takes an object and recursively prints all
// the classes in that object's hierarchy.
import static net.mindview.util.Print.*;
class A{}
class B extends A{}
class C extends B{}
public class Ja14_8 {
static void f(Class c){
print(c.getName());
try{
f(c.getSuperclass());
}catch(Exception e){
}
}
public static void main(String[] args) {
if(args.length<1)System.exit(0);
Class c=null;
try{
c=Class.forName(args[0]);
print(c.getName()+" "+c.isInterface()+" "/*+c.getSuperclass().getSuperclass()*/);
f(c);
//c.getClass().mm();
}catch(ClassNotFoundException e){}
}
}
//用了递归!!
PS: 用了递归!!
练习9:
// Modify the previous exercise so that it uses Class.getDeclaredFields()
// to also display information about the fields in a class.
import static net.mindview.util.Print.*;
class A{}
class B extends A{}
class C extends B{}
public class Ja14_9 {
static void f(Class c){
print(c.getName());
try{
f(c.getSuperclass());
}catch(Exception e){
}
}
public static void main(String[] args) {
if(args.length<1)System.exit(0);
Class c=null;
try{
c=Class.forName(args[0]);
print(c.getDeclaredFields());
//f(c);
}catch(ClassNotFoundException e){}
}
}
练习10:
// Write a program to determine whether an array of char is a primitive type
// or a true Object.
import static net.mindview.util.Print.*;
public class Ja14_10{
public static void main(String[] args){
char[] a=new char[5];
print(a.getClass().getName());
}
}
//char[]是基本类型
练习11:
练习12:
// Use TypeCounter with the CoffeeGenerator.java class in the Generics chapter.
import java.util.*;
import generics.coffee.*;
class TypeCounter extends HashMap,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))
countClass(superClass);
}
public String toString() {
StringBuilder result = new StringBuilder("{");
for(Map.Entry,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();
}
}
public class Ja14_12{
public static void main(String[] args){
TypeCounter tc=new TypeCounter(Coffee.class);
for(Coffee c : new CoffeeGenerator(5)){
tc.count(c);
}
System.out.println(tc);
}
}
练习13:
// Use TypeCounter with the RegisteredFactories.java class in this chapter.
import typeinfo.factory.*;
import java.util.*;
class Part {
public String toString() {
return getClass().getSimpleName();
}
static List> partFactories =
new ArrayList>();
static {
// Collections.addAll() gives an "unchecked generic
// array creation ... for varargs parameter" warning.
partFactories.add(new FuelFilter.Factory());
partFactories.add(new AirFilter.Factory());
partFactories.add(new CabinAirFilter.Factory());
partFactories.add(new OilFilter.Factory());
partFactories.add(new FanBelt.Factory());
partFactories.add(new PowerSteeringBelt.Factory());
partFactories.add(new GeneratorBelt.Factory());
}
private static Random rand = new Random(47);
public static Part createRandom() {
int n = rand.nextInt(partFactories.size());
return partFactories.get(n).create();
}
}
class Filter extends Part {}
class FuelFilter extends Filter {
// Create a Class Factory for each specific type:
public static class Factory
implements typeinfo.factory.Factory {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public PowerSteeringBelt create() {
return new PowerSteeringBelt();
}
}
}
class TypeCounter extends HashMap,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))
countClass(superClass);
}
public String toString() {
StringBuilder result = new StringBuilder("{");
for(Map.Entry,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();
}
}
public class Ja14_13{
public static void main(String[] args){
TypeCounter tc=new TypeCounter(Part.class);
for(int i = 0; i < 10; i++)
tc.count(Part.createRandom());
System.out.println(tc);
}
}
练习14:
/* A constructor is a kind of factory method. Modify RegisteredFactories.java
* so that instead of using explicit factories, the class object is stored in
* the List, and newInstance() is used to create each object.
*/
import typeinfo.factory.*;
import java.util.*;
class Part {
public String toString() {
return getClass().getSimpleName();
}
static List> partClasses =
new ArrayList>();
static {
// Collections.addAll() gives an "unchecked generic
// array creation ... for varargs parameter" warning.
partClasses.add(FuelFilter.class);
partClasses.add(AirFilter.class);
partClasses.add(CabinAirFilter.class);
partClasses.add(OilFilter.class);
partClasses.add(FanBelt.class);
partClasses.add(PowerSteeringBelt.class);
partClasses.add(GeneratorBelt.class);
}
private static Random rand = new Random(47);
public static Part createRandom() {
int n = rand.nextInt(partClasses.size());
try{return partClasses.get(n).newInstance();
}catch(InstantiationException e){
throw new RuntimeException(e);
}catch(IllegalAccessException e){
throw new RuntimeException(e);
}
}
}
class Filter extends Part {}
class FuelFilter extends Filter {
// Create a Class Factory for each specific type:
public static class Factory
implements typeinfo.factory.Factory {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public PowerSteeringBelt create() {
return new PowerSteeringBelt();
}
}
}
public class Ja14_14 {
public static void main(String[] args) {
for(int i = 0; i < 10; i++)
System.out.println(Part.createRandom());
}
}
练习15:
/* Implement a new PetCreator using Registered Factories, and modify the Pets
* Facade so that it uses this one instead of the other two. Ensure that the
* rest of the examples that use Pets.java still work correctly.
*/
import typeinfo.pets.*;
import typeinfo.factory.*;
import java.util.*;
public class PetFactory{
static List> petFactories=new ArrayList>();
static{
//System.out.println(new Rodent.Factory());
petFactories.add(new Pet.Factory());
petFactories.add(new Cat.Factory());
petFactories.add(new Cymric.Factory());
petFactories.add(new Dog.Factory());
petFactories.add(new EgyptianMau.Factory());
//petFactories.add(new Gerbil.Factory());
//petFactories.add(new Hamster.Factory());
petFactories.add(new Manx.Factory());
//petFactories.add(new Mouse.Factory());
petFactories.add(new Mutt.Factory());
petFactories.add(new Pug.Factory());
//petFactories.add(new Rat.Factory());
//petFactories.add(new Rodent.Factory());//!无法找到??
}
private static Random rand=new Random(55);
public static Pet createRandom(){
return petFactories.get(rand.nextInt(petFactories.size())).create();
}
public static void main(String[] args){
for(int i=0;i<10;i++)
System.out.println(PetFactory.createRandom());
}
}
import typeinfo.pets.*;
import java.util.*;
public class Pets {
public static final PetCreator creator =
new LiteralPetCreator();
public static Pet randomPet() {
return PetFactory.createRandom()/*.randomPet()*/;
}
public static Pet[] createArray(int size) {
return creator.createArray(size);
}
public static ArrayList arrayList(int size) {
return creator.arrayList(size);
}
public static void main(String[] args){
for(int i=0;i<10;i++)
System.out.println(Pets.randomPet());
}
}
练习16:
// Modify the Coffee hierarchy in the Generics chapter to use Registered Factories.
import typeinfo.factory.*;
import generics.coffee.*;
import java.util.*;
import net.mindview.util.*;
public class Ja14_16 implements Generator, Iterable{
private static List> coFactory=new ArrayList>();
static{
coFactory.add(new Coffee.Factory());
coFactory.add(new Americano.Factory());
coFactory.add(new Breve.Factory());
coFactory.add(new Cappuccino.Factory());
coFactory.add(new Latte.Factory());
coFactory.add(new Mocha.Factory());
}
private static Random rand = new Random(66);
public Ja14_16() {}
private int size = 0;
public Ja14_16(int sz) { size = sz; }
public Coffee next() {
try {
return (Coffee)
coFactory.get(rand.nextInt(coFactory.size())).create();
// Report programmer errors at run time:
} catch(Exception e) {
throw new RuntimeException(e);
}
}
class CoffeeIterator implements Iterator {
int count = size;
public boolean hasNext() { return count > 0; }
public Coffee next() {
count--;
return Ja14_16.this.next();
}
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
public Iterator iterator() {
return new CoffeeIterator();
}
public static void main(String[] args) {
Ja14_16 gen = new Ja14_16();
for(int i = 0; i < 5; i++)
System.out.println(gen.next());
for(Coffee c : new Ja14_16(5))
System.out.println(c);
}
}
练习17:
// Modify the regular expression in ShowMethods.java to additionally
// strip off the keywords native and final (hint: us the OR operator '|').
// {Args: Ja14_17}
import java.lang.reflect.*;
import java.util.regex.*;
import static net.mindview.util.Print.*;
public class Ja14_17 {
private static String usage =
"usage:\n" +
"ShowMethods qualified.class.name\n" +
"To show all methods in class or:\n" +
"ShowMethods qualified.class.name word\n" +
"To search for methods involving 'word'";
private static Pattern p = Pattern.compile("(\\w+\\.)|(final)|(native)");
public static void main(String[] args) {
if(args.length < 1) {
print(usage);
System.exit(0);
}
int lines = 0;
try {
Class> c = Class.forName(args[0]);
Method[] methods = c.getMethods();
Constructor[] ctors = c.getConstructors();
if(args.length == 1) {
for(Method method : methods)
print(
p.matcher(method.toString()).replaceAll(""));
for(Constructor ctor : ctors)
print(p.matcher(ctor.toString()).replaceAll(""));
lines = methods.length + ctors.length;
} else {
for(Method method : methods)
if(method.toString().indexOf(args[1]) != -1) {
print(
p.matcher(method.toString()).replaceAll(""));
lines++;
}
for(Constructor ctor : ctors)
if(ctor.toString().indexOf(args[1]) != -1) {
print(p.matcher(
ctor.toString()).replaceAll(""));
lines++;
}
}
} catch(ClassNotFoundException e) {
print("No such class: " + e);
}
}
}
练习18:
// Make ShowMethods a non-public class and verify that the synthesized default
// constructor no longer shows up in the output.
// {Args: Ja14_18}
import java.lang.reflect.*;
import java.util.regex.*;
import static net.mindview.util.Print.*;
class Ja14_18 {
private static String usage =
"usage:\n" +
"ShowMethods qualified.class.name\n" +
"To show all methods in class or:\n" +
"ShowMethods qualified.class.name word\n" +
"To search for methods involving 'word'";
private static Pattern p = Pattern.compile("\\w+\\.");
public static void main(String[] args) {
if(args.length < 1) {
print(usage);
System.exit(0);
}
int lines = 0;
try {
Class> c = Class.forName(args[0]);
Method[] methods = c.getMethods();
Constructor[] ctors = c.getConstructors();
if(args.length == 1) {
for(Method method : methods)
print(
p.matcher(method.toString()).replaceAll(""));
for(Constructor ctor : ctors)
print(p.matcher(ctor.toString()).replaceAll(""));
lines = methods.length + ctors.length;
} else {
for(Method method : methods)
if(method.toString().indexOf(args[1]) != -1) {
print(
p.matcher(method.toString()).replaceAll(""));
lines++;
}
for(Constructor ctor : ctors)
if(ctor.toString().indexOf(args[1]) != -1) {
print(p.matcher(
ctor.toString()).replaceAll(""));
lines++;
}
}
} catch(ClassNotFoundException e) {
print("No such class: " + e);
}
}
}
练习19:
// In ToyTest.java, use reflection to create a Toy object using
// the non-default constructor.
import typeinfo.toys.*;
import static net.mindview.util.Print.*;
import java.lang.reflect.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
class Toy {
// Comment out the following default constructor
// to see NoSuchMethodError from (*1*)
Toy() {}
Toy(int i) {print("sda");}
public String toString(){
return "it's Toy";
}
}
class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots {
FancyToy() { super(1); }
}
public class Ja14_19 {
static void printInfo(Class cc) {
print("Class name: " + cc.getName() +
" is interface? [" + cc.isInterface() + "]");
print("Simple name: " + cc.getSimpleName());
print("Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
/*Class c = null;
try {
c = Class.forName("typeinfo.toys.FancyToy");
} catch(ClassNotFoundException e) {
print("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
for(Class face : c.getInterfaces())
printInfo(face);
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
obj = up.newInstance();
} catch(InstantiationException e) {
print("Cannot instantiate");
System.exit(1);
} catch(IllegalAccessException e) {
print("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());*/
try{
print(Toy.class.getDeclaredConstructor(int.class).newInstance(1));
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
练习20:
/* Look up the interface for java.lang.Class in the JDK decumentation from
* http://java.sun.com. Write a program that takes the name of a class as a
* command line argument, then uses the Class methods to dump all the
* information available for that class. Test your prgram with a standard
* library class and a class you create.
*/
import static net.mindview.util.Print.*;
import java.lang.reflect.*;
import java.lang.annotation.*;
public class Ja14_20{
public static void main(String[] args){
if(args.length<1)System.exit(0);
Class> c=null;
try{
c=Class.forName(args[0]);
}catch(Exception e){
throw new RuntimeException(e);
}
for(Annotation a:c.getAnnotations())print(a);
for(Constructor a:c.getConstructors())print(a);
for(Field a:c.getFields())print(a);
//for(Method a:c.getMethods())print(a);
for(Class a:c.getClasses())print(a);
for(Annotation a : c.getDeclaredAnnotations())
print(a);
for(Method m : c.getDeclaredMethods())
print(m);
for(Type t : c.getGenericInterfaces())
print(t);
print("c.isInterface(): " + c.isInterface());
print("c.getTypeParameters(): " + c.getTypeParameters());
print("c.isAnnotation(): " + c.isAnnotation());
print("c.isAnnotationPresent(Documented.class): " + c.isAnnotationPresent(Documented.class));
print("c.isAnonymousClass(): " + c.isAnonymousClass());
print("c.isArray(): " + c.isArray());
print("c.isAssignableFrom(Object.class): " + c.isAssignableFrom(Object.class));
print("c.isEnum(): " + c.isEnum());
print("c.isInstance(Object.class): " + c.isInstance(Object.class));
print("c.isInterface(): " + c.isInterface());
print("c.isLocalClass(): " + c.isLocalClass());
print("c.isMemberClass(): " + c.isMemberClass());
print("c.isPrimitive(): " + c.isPrimitive());
print("c.isSynthetic(): " + c.isSynthetic());
}
}
练习21:
// Modify SimpleProxyDemo.java so that it measures method-call times.
import static net.mindview.util.Print.*;
interface Interface {
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface {
public void doSomething() { print("doSomething"); }
public void somethingElse(String arg) {
print("somethingElse " + arg);
}
}
class SimpleProxy implements Interface {
private static int count=0;
private static int scount=0;
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
public void doSomething() {
print("SimpleProxy doSomething");
proxied.doSomething();
print(++count);
}
public void somethingElse(String arg) {
print("SimpleProxy somethingElse " + arg);
proxied.somethingElse(arg);
print(++scount);
}
}
class Ja14_21 {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
}
练习22:
// Modify SimpleDynamicProxy.java so that it measures method-call times.
import java.lang.reflect.*;
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("**** proxy: " + proxy.getClass() +
", method: " + method + ", args: " + args);
if(args != null)
for(Object arg : args)
System.out.println(" " + arg);
return method.invoke(proxied, args);
}
}
class Ja14_22 {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
RealObject real = new RealObject();
SimpleProxy sim=new SimpleProxy(real);
consumer(sim);
// Insert a proxy and call again:
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{ Interface.class },
new DynamicProxyHandler(sim));
consumer(proxy);
}
}
练习23:
// Inside invoke() in SimpleDynamicProxy.java, try to print the proxy argument and explain
// what happens.
import java.lang.reflect.*;
class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
this.proxied = proxied;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("**** proxy: " + proxy.getClass() +
", method: " + method + ", args: " + args);
if(args != null)
for(Object arg : args)
System.out.println(" " + arg);
System.out.println(proxy);
return method.invoke(proxied, args);
}
}
class Ja14_23 {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
RealObject real = new RealObject();
SimpleProxy sim=new SimpleProxy(real);
consumer(sim);
// Insert a proxy and call again:
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[]{ Interface.class },
new DynamicProxyHandler(sim));
consumer(proxy);
}
}
//invoke调用print打印proxy,print操作又会调用invoke,产生了无限循环。
练习24:
// Add Null Objects to RegisteredFactories.java.
import typeinfo.factory.*;
import java.util.*;
class Part {
public String toString() {
return getClass().getSimpleName();
}
static List> partFactories =
new ArrayList>();
static {
// Collections.addAll() gives an "unchecked generic
// array creation ... for varargs parameter" warning.
partFactories.add(new FuelFilter.Factory());
partFactories.add(new AirFilter.Factory());
partFactories.add(new CabinAirFilter.Factory());
partFactories.add(new OilFilter.Factory());
partFactories.add(new FanBelt.Factory());
partFactories.add(new PowerSteeringBelt.Factory());
partFactories.add(new GeneratorBelt.Factory());
partFactories.add(new NullPart.Factory());
}
private static Random rand = new Random(66);
public static Part createRandom() {
int n = rand.nextInt(partFactories.size());
return partFactories.get(n).create();
}
}
interface Null{}
class NullPart extends Part implements Null{
public final static Part NULL=new NullPart();
public static class Factory implements typeinfo.factory.Factory{
public NullPart create(){return (NullPart)NULL;}
}
public String toString(){return "it's NullPart";}
}
class Filter extends Part {}
class FuelFilter extends Filter {
// Create a Class Factory for each specific type:
public static class Factory implements typeinfo.factory.Factory {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory {
public PowerSteeringBelt create() {
return new PowerSteeringBelt();
}
}
}
public class Ja14_24 {
public static void main(String[] args) {
for(int i = 0; i < 10; i++)
System.out.println(Part.createRandom());
}
}
练习25:
/* Create a class containing private, protected and package-access methods.
* Write code to access these methods from outside of the class's package.
*/
import static net.mindview.util.Print.*;
import java.lang.reflect.*;
import typeinfo.packageaccess.*;
public class Ja14_25{
public static void main(String[] agrs){
DD d=new DD();
try{
Method u=d.getClass().getDeclaredMethod("u");
u.setAccessible(true);
u.invoke(d);
}catch(Exception e){throw new RuntimeException(e);}
}
}
练习26:
// Implement clearSpitValve() as described in the summary.
import polymorphism.music.Note;
import java.util.*;
import static net.mindview.util.Print.*;
class Instrument {
void play(Note n) { print("Instrument.play() " + n); }
public String toString() { return "Instrument"; }
void adjust() { print("Adjusting Instrument"); }
}
class Wind extends Instrument {
void play(Note n) { print("Wind.play() " + n); }
public String toString() { return "Wind"; }
void adjust() { print("Adjusting Wind"); }
void clearSpitValve() { print("Wind clearing spit valve"); }
}
class Percussion extends Instrument {
void play(Note n) { print("Percussion.play() " + n); }
public String toString() { return "Percussion"; }
void adjust() { print("Adjusting Percussion"); }
}
class Stringed extends Instrument {
void play(Note n) { print("Stringed.play() " + n); }
public String toString() { return "Stringed"; }
void adjust() { print("Adjusting Stringed"); }
}
class Keyboard extends Instrument {
void play(Note n) { print("Keyboard.play() " + n); }
public String toString() { return "Keyboard"; }
void adjust() { print("Adjusting Keyboard"); }
}
class Brass extends Wind {
void play(Note n) { print("Brass.play() " + n); }
public String toString() { return "Brass"; }
void adjust() { print("Adjusting Brass"); }
void clearSpitValve() { print("Brass clearing spit valve"); }
}
class Woodwind extends Wind {
void play(Note n) { print("Woodwind.play() " + n); }
public String toString() { return "Woodwind"; }
void clearSpitValve() { print("Woodwind clearing spit valve"); }
}
class Piano extends Keyboard {
void play(Note n) { print("Piano.play() " + n); }
public String toString() { return "Piano"; }
}
class RandomInstrumentGenerator {
private Random rand = new Random();
public Instrument next() {
switch(rand.nextInt(7)) {
default:
case 0: return new Wind();
case 1: return new Percussion();
case 2: return new Stringed();
case 3: return new Keyboard();
case 4: return new Brass();
case 5: return new Woodwind();
case 6: return new Piano();
}
}
}
public class Ja14_26 {
// Doesn't care about type, so new types
// added to the system still work right:
public static void tune(Instrument i) {
//...
i.play(Note.MIDDLE_C);
}
public static void tuneAll(Instrument[] e) {
for(Instrument i : e)
tune(i);
}
private static RandomInstrumentGenerator gen = new RandomInstrumentGenerator();
public static void main(String[] args) {
// Upcasting during addition to the array:
Instrument[] orchestra = new Instrument[20];
// fill up orchestra array wth instruments:
for(int i = 0; i < orchestra.length; i++)
orchestra[i] = gen.next();
for(Instrument i : orchestra) {
if(i instanceof Wind) // get RTTI
((Wind)i).clearSpitValve();
i.adjust();
}
tuneAll(orchestra);
}
}