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<Class<?>,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<Class<?>,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<Factory<? extends Part>> partFactories =
new ArrayList<Factory<? extends Part>>();
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<FuelFilter> {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<AirFilter> {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<CabinAirFilter> {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<OilFilter> {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<FanBelt> {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<GeneratorBelt> {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<PowerSteeringBelt> {
public PowerSteeringBelt create() {
return new PowerSteeringBelt();
}
}
}
class TypeCounter extends HashMap<Class<?>,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<Class<?>,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<Class<? extends Part>> partClasses =
new ArrayList<Class<? extends Part>>();
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<FuelFilter> {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<AirFilter> {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<CabinAirFilter> {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<OilFilter> {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<FanBelt> {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<GeneratorBelt> {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<PowerSteeringBelt> {
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<Factory<? extends Pet>> petFactories=new ArrayList<Factory<? extends Pet>>();
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<Pet> 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<Coffee>, Iterable<Coffee>{
private static List<Factory<? extends Coffee>> coFactory=new ArrayList<Factory<? extends Coffee>>();
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<Coffee> {
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<Coffee> 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<Factory<? extends Part>> partFactories =
new ArrayList<Factory<? extends Part>>();
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<NullPart>{
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<FuelFilter> {
public FuelFilter create() { return new FuelFilter(); }
}
}
class AirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<AirFilter> {
public AirFilter create() { return new AirFilter(); }
}
}
class CabinAirFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<CabinAirFilter> {
public CabinAirFilter create() {
return new CabinAirFilter();
}
}
}
class OilFilter extends Filter {
public static class Factory
implements typeinfo.factory.Factory<OilFilter> {
public OilFilter create() { return new OilFilter(); }
}
}
class Belt extends Part {}
class FanBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<FanBelt> {
public FanBelt create() { return new FanBelt(); }
}
}
class GeneratorBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<GeneratorBelt> {
public GeneratorBelt create() {
return new GeneratorBelt();
}
}
}
class PowerSteeringBelt extends Belt {
public static class Factory
implements typeinfo.factory.Factory<PowerSteeringBelt> {
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程式設計思想》第四版 第2 章 一切都是物件 2 . 3 絕對不要清除物件
在大多數程式設計語言中,變數的“存在時間”(Lifetime)一直是程式設計師需要著重考慮的問題。變數應持 續多長的時間?如果想清除它,那麼何時進行?在變數存在時間上糾纏不清會造成大量的程式錯誤。在下面 的小節裡,將闡示Java 如何幫助我們完成所有清除工作
Java-Java程式設計思想第四版 第十五章 練習
練習1:// Use Holder3 with the typeinfo.pets library to show that a Holder3 that is // specified to hold a base type can also hold a derived
Java程式設計思想第四版第六章練習
練習1:在某個包中建立一個類,在這個類所處的包的外部建立該類的一個例項。 package exercise6; import Exercise5.Exercise5_22; public cla
Java-Java程式設計思想第四版 第十章 練習
練習1:/* Write a class named Outer that contains an inner class named Innet. * Add a method to Outer that returns an object of type Inner.
Java-Java程式設計思想第四版 第十一章 練習
練習1:/* Create a new class called Gerbil with an int gerbilNumber that's * initialized in the constructor. Give it a method called hop() t
Java-Java程式設計思想第四版 第十二章 練習
練習1:/* Create a class with a main(0 that throws an object of class Exception * inside a try block. Give the constructor for Exception a St
Java-Java程式設計思想第四版 第七章 練習
練習1:(2)建立一個簡單的類。第二個類中,將一個引用定義為第一個類的物件。運用惰性初始化來例項化 這個物件。 public class Ja7_1{ First f; First getFirst(){ if(f==null){
Java程式設計思想第四版第十二章學習——通過異常處理錯誤(1)
使用異常帶來的好處: 它降低了錯誤處理程式碼的複雜度。使用異常後,不需要檢查特定的錯誤並在程式中的許多地方去處理它。因為異常機制將保證能夠捕獲這個錯誤且只需在一個地方處理錯誤,即異常處理程式中。 1、基本異常 異常情形:阻止當前方法或作用域繼續執行的問
Java-Java程式設計思想第四版 第十七章 容器深入研究 練習
練習1:/* Create a List (try both ArrayList and LinkedList) and fill it using * Countries. Sort the list and print it, then apply Collections
Java程式設計思想第四版第十一章學習——持有物件
1、基本概念 Java容器類類庫的作用是“儲存物件”,分為 1)Collection.一個獨立元素的序列,這些元素都服從一條或多條規則。List必須按照插入的順序儲存元素,而Set不能有重複元素。Queue按照排隊規則來確定物件產生的順序(通常與他們被插入的
Java程式設計思想第四版-第四章(控制執行流程 )筆記
第四章 控制執行流程 有一定java基礎的其實這一章節都懂的。。。。主要記一些細節。(斷句,和switch的 用法。) if- else while do-while
Java-Java程式設計思想第四版 第十八章 Java I/O系統 練習
練習1:/* Modify OSExecute.java so that, instead of printing the standard output stream * it returns the results of executing the program as
《Java程式設計思想第四版》筆記---21章(1) 併發
執行緒是程序中一個任務控制流序列,由於程序的建立和銷燬需要銷燬大量的資源,而多個執行緒之間可以共享程序資料,因此多執行緒是併發程式設計的基礎。 多核心CPU可以真正實現多個任務並行執行,單核心CPU程式其實不是真正的並行執行,而是通過時間片切換來執行,由於時間片切換頻繁,使
Java-Java程式設計思想第四版 第十四章 練習
練習1:// In ToyTest.java, comment out Toy's default constructor and // explain what happens. import static net.mindview.util.Print.*; inter
Java-Java程式設計思想第四版 第九章 練習
練習abstract class A{ abstract void print(); public A(){print();} } public class Ja9_1_3 extends A{ int i=5; void print(){
Java程式設計思想第四版第四章練習
練習1:寫一個程式,列印從1到100的值。 public class Exercise4_1 { public static void main(String[] args) { fo
Java程式設計思想第四版第七章練習
練習1:建立一個簡單的類。第二個類中,將一個引用定義為第一個類的物件。運用惰性初始化來例項化 這個物件 public class Exercise7_1 { public static
Java-Java程式設計思想第四版 第十九章 列舉型別 練習
練習1// Use a static import to modify TrafficLight.java so you // don't have to qualify the enum instances. import static enumerated.Signal
java編程思想第四版第9章
art new end strac override @override err private over 練習3: public class MainTest { public static void main(String args
java編程思想第四版第五章習題
調用構造 每次 override 變參 對象賦值 turn AC 初始化 @override 創建一個類, 它包含一個未初始化的String引用。驗證該引用被Java初始化成了null package net.mindview.initialization; publ