Java-Java编程思想第四版 第十四章 练习

练习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);
	}
}

你可能感兴趣的:(Java-Java编程思想第四版 第十四章 练习)