Java编程思想第四版第十四章习题

1 In ToyTest.java, comment out Toy's default constructor and explain what happens.

package job;
import java.util.*;

interface HasBatteries {}

interface Waterproof {}

interface Shoots {}



class Toy {

    //Toy() {}

    Toy(int i) {}

}



class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {

    FancyToy() {
        super(1);
    }

}



public class Main {

    static void printInfo(Class cc) {

        System.out.println("Class name: " + cc.getName() +

                " is interface? [" + cc.isInterface() + "]");

        System.out.println("Simple name: " + cc.getSimpleName());

        System.out.println("Canonical name : " + cc.getCanonicalName());

    }

    public static void main(String[] args) {

        Class c = null;

        try {

            c = Class.forName("job.FancyToy");

        } catch (ClassNotFoundException e) {

            System.out.println("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) {

            System.out.println("Cannot instantiate");

            System.exit(1);

        } catch (IllegalAccessException e) {

            System.out.println("Cannot access");

            System.exit(1);

        }

        printInfo(obj.getClass());

    }

}

output:

 Class name: job.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : job.FancyToy
Class name: job.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : job.HasBatteries
Class name: job.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : job.Waterproof
Class name: job.Shoots is interface? [true]
Simple name: Shoots
Canonical name : job.Shoots
Cannot instantiate

 

2 Incorporate a new kind of interface into ToyTest.java andverify that it is detected and displayed properly.

package job;
import java.util.*;

interface HasBatteries {}

interface Waterproof {}

interface Shoots {}

interface A{}



class Toy {

    Toy() {}

    Toy(int i) {}

}



class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots,A {

    FancyToy() {
        super(1);
    }

}



public class Main {

    static void printInfo(Class cc) {

        System.out.println("Class name: " + cc.getName() +

                " is interface? [" + cc.isInterface() + "]");

        System.out.println("Simple name: " + cc.getSimpleName());

        System.out.println("Canonical name : " + cc.getCanonicalName());

    }

    public static void main(String[] args) {

        Class c = null;

        try {

            c = Class.forName("job.FancyToy");

        } catch (ClassNotFoundException e) {

            System.out.println("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) {

            System.out.println("Cannot instantiate");

            System.exit(1);

        } catch (IllegalAccessException e) {

            System.out.println("Cannot access");

            System.exit(1);

        }

        printInfo(obj.getClass());

    }

}

output:

Class name: job.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : job.FancyToy
Class name: job.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : job.HasBatteries
Class name: job.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : job.Waterproof
Class name: job.Shoots is interface? [true]
Simple name: Shoots
Canonical name : job.Shoots
Class name: job.A is interface? [true]
Simple name: A
Canonical name : job.A
Class name: job.Toy is interface? [false]
Simple name: Toy
Canonical name : job.Toy
 

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.

package job;
import java.util.*;
abstract class Shape{
    abstract void draw();
    abstract void erase();
}
class Rhomboid extends Shape{

    public void draw() { System.out.println("Rhomboid.draw()"); }

    public void erase() { System.out.println("Rhomboid.erase()"); }

}

class Circle extends Shape{

    public void draw() { System.out.println("Circle.draw()"); }

    public void erase() { System.out.println("Circle.erase()"); }

}
public class Main {


    public static void main(String[] args) {
        try {
            Shape a = new Rhomboid();

            a.draw();

            ((Rhomboid) a).draw();

            ((Circle) a).draw();
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }

}

output:

Rhomboid.draw()
Rhomboid.draw()
java.lang.ClassCastException: class job.Rhomboid cannot be cast to class job.Circle (job.Rhomboid and job.Circle are in unnamed module of loader 'app')
    at job.Main.main(Main.java:33)

 

4 Modify the previous exercise so that it uses instancof to check the type before performing the downcast.

package job;
import java.util.*;
abstract class Shape{
    abstract void draw();
    abstract void erase();
}
class Rhomboid extends Shape{

    public void draw() { System.out.println("Rhomboid.draw()"); }

    public void erase() { System.out.println("Rhomboid.erase()"); }

}

class Circle extends Shape{

    public void draw() { System.out.println("Circle.draw()"); }

    public void erase() { System.out.println("Circle.erase()"); }

}
public class Main {


    public static void main(String[] args) {
        try {
            Shape a = new Rhomboid();
            if(a instanceof Shape) {
                a.draw();
            }
            if(a instanceof Rhomboid) {
                ((Rhomboid) a).draw();
            }
            else if(a instanceof Circle) {
                ((Circle) a).draw();
            }
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }

}

 

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).

package job;
import java.util.*;
class Shape {

    public void draw() {
    }

    public void erase() {
    }

    public void rotate() {
    }

}

class Square extends Shape {

    public void draw() {
        System.out.println("Square.draw()");
    }

    public void erase() {
        System.out.println("Square.erase()");
    }

    public void rotate() {
        System.out.println("Square.rotate()");
    }

}

class Triangle extends Shape {

    public void draw() {
        System.out.println("Triangle.draw()");
    }

    public void erase() {
        System.out.println("Triangle.erase()");
    }

    public void rotate() {
        System.out.println("Triangle.rotate()");
    }

}

class Circle extends Shape {

    public void draw() {
        System.out.println("Circle.draw()");
    }

    public void erase() {
        System.out.println("Circle.erase()");
    }

    public void rotate() {
        System.out.println("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 Main {

    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();

        }

    }
}

 output:

Radom

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."

package job;
import java.util.*;
class Shape {
    boolean flag=false;

    public void draw() {
    }

    public void erase() {
    }

    public void rotate() {
    }

    void flag() {
    }
}

class Square extends Shape {

    public void draw() {
        System.out.println("Square.draw()");
    }

    public void erase() {
        System.out.println("Square.erase()");
    }

    public void rotate() {
        System.out.println("Square.rotate()");
    }

    void flag() {
        flag = true;
    }

    public String toString() {
        return ("Square: " + flag);
    }
}

class Triangle extends Shape {

    public void draw() {
        System.out.println("Triangle.draw()");
    }

    public void erase() {
        System.out.println("Triangle.erase()");
    }

    public void rotate() {
        System.out.println("Triangle.rotate()");
    }

    void flag() {
        flag = true;
    }

    public String toString() {
        return ("Triangle: " + flag);
    }
}

class Circle extends Shape {

    public void draw() {
        System.out.println("Circle.draw()");
    }

    public void erase() {
        System.out.println("Circle.erase()");
    }

    public void rotate() {
        System.out.println("Circle.rotate()");
    }

    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 Main {

    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 a : s) {

            if (!(a instanceof Circle)) {
                a.rotate();
                a.flag();
                System.out.println(a);
            }
        }

    }
}

output:

Radom 

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.

package job;
import java.util.*;
class Candy {
    static {
        System.out.println("Loading Candy");
    }
}
class Gum {
    static {
        System.out.println("Loading Gum");
    }
}

class Cookie {
    static {
        System.out.println("Loading Cookie");
    }
}


class Main{
    public static void main(String[] args){
        Other.main(new String[]{"job.Candy"});
    }
}

class Other {


    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("args is null");
            System.exit(0);
        }
        Class c = null;
        try {
            c = Class.forName(args[0]);
            System.out.println(c.getName() + " " + c.isInterface());
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
    }
}

output:

Loading Candy
job.Candy false 

8 Write a method that takes an object and recursively prints allthe classes in that object's hierarchy.

 

package job;
import java.util.*;
class A{

}
class B extends A{

}
class C extends B{

}
public class Main{
    static void Aa(Class obj){
        System.out.println(obj.getName());
        try{
            Aa(obj.getSuperclass());
        }catch (Exception e){}
    }
    public static void main(String[] args){
        Class c=null;
        try{
            c=Class.forName("job.C");
            Aa(c);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }
}

output:

job.C
job.B
job.A
java.lang.Object 

9 Modify the previous exercise so that it uses Class.getDeclaredFields()to also display information about the fields in a class.

 

package job;
import java.util.*;
class A{

}
class B extends A{

}
class C extends B{

}
public class Main{
    static void Aa(Class obj){
        System.out.println(obj.getName());
        try{
            Aa(obj.getSuperclass());
        }catch (Exception e){}
    }
    public static void main(String[] args){
        Class c=null;
        try{
            c=Class.forName("job.C");
            System.out.println(c.getDeclaredFields());
            Aa(c);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }
}

output:

[Ljava.lang.reflect.Field;@34ce8af7
job.C
job.B
job.A
java.lang.Object 

10 Write a program to determine whether an array of char is a primitive type or a true Object.

package job;
import java.util.*;

public class Main{
    static void Aa(Class obj){
        System.out.println(obj.getName());
        try{
            Aa(obj.getSuperclass());
        }catch (Exception e){}
    }
    public static void main(String[] args){
        char[] a=new char[5];
        try{
            Class c=a.getClass();
            Aa(c);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }
}

output:

[C
java.lang.Object

故:对象

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 Main{

    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 Main{

    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.

package job;
import java.util.*;
interface Factory{
    T create();
}

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 Main {

    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.

package job;
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.

package job;
import typeinfo.factory.*;

import generics.coffee.*;

import java.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 '|').


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.


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,Java变成思想)