14章类型信息-----动态代理-----空对象----接口与类型信息

来源:互联网 发布:大黄蜂视频加密软件 编辑:程序博客网 时间:2024/06/06 22:45

动态代理,这里只能是用接口,用抽象类的话,运行会报错

1、接口:

interface Interface {
 void doSomething();
 void somethingElse(String arg);
}

2、实现类:

class RealObject implements Interface {
 public void doSomething() {System.out.println("doSomething"); }
 public void somethingElse(String arg) {
   System.out.println("somethingElse " + arg);
 }
}

3、调用处理器:

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("代理了");
    if(args != null){
      for(Object arg : args)
        System.out.println("参数是:" + arg);
    }
    return method.invoke(proxied, args);
  }
}

4:测试类:

public class SimpleDynamicProxy {
 
  public static void main(String[] args) {
    RealObject real = new RealObject();
    Interface proxy = (Interface)Proxy.newProxyInstance(
      Interface.class.getClassLoader(),
      new Class[]{ Interface.class },
      new DynamicProxyHandler(real));
    proxy.doSomething();
    proxy.somethingElse("要开始了哦哦哦哦");
  }
}



-----------------------------------------------------空对象-----------------------------------------------------

1、空接口:

public interface Null {}

2、person类:

import net.mindview.util.*;


class Person {
  public final String first;
  public final String last;
  public final String address;
  // etc.
  public Person(String first, String last, String address){
    this.first = first;
    this.last = last;
    this.address = address;
  }
  public String toString() {
    return "Person: " + first + " " + last + " " + address;
  }
  public static class NullPerson
  extends Person implements Null {
    private NullPerson() { super("None", "None", "None"); }
    public String toString() { return "NullPerson"; }
  }
  public static final Person NULL = new NullPerson();
}

3、position职位类:

class Position {
  private String title;
  private Person person;
  public Position(String jobTitle, Person employee) {
    title = jobTitle;
    person = employee;
    if(person == null)
      person = Person.NULL;
  }
  public Position(String jobTitle) {
    title = jobTitle;
    person = Person.NULL;
  }
  public String getTitle() { return title; }
  public void setTitle(String newTitle) {
    title = newTitle;
  }
  public Person getPerson() { return person; }
  public void setPerson(Person newPerson) {
    person = newPerson;
    if(person == null)
      person = Person.NULL;
  }
  public String toString() {
    return "Position: " + title + " " + person;
  }

4、staff类:

//: typeinfo/Staff.java
import java.util.*;


public class Staff extends ArrayList<Position> {
  public void add(String title, Person person) {
    add(new Position(title, person));
  }
  public void add(String... titles) {
    for(String title : titles)
      add(new Position(title));
  }
  public Staff(String... titles) { add(titles); }
  public boolean positionAvailable(String title) {
    for(Position position : this)
      if(position.getTitle().equals(title) &&
         position.getPerson() == Person.NULL)
        return true;
    return false;
  }
  public void fillPosition(String title, Person hire) {
    for(Position position : this)
      if(position.getTitle().equals(title) &&
         position.getPerson() == Person.NULL) {
        position.setPerson(hire);
        return;
      }
    throw new RuntimeException(
      "Position " + title + " not available");
  }
  public static void main(String[] args) {
    Staff staff = new Staff("President", "CTO",
      "Marketing Manager", "Product Manager",
      "Project Lead", "Software Engineer",
      "Software Engineer", "Software Engineer",
      "Software Engineer", "Test Engineer",
      "Technical Writer");
    staff.fillPosition("President",
      new Person("Me", "Last", "The Top, Lonely At"));
    staff.fillPosition("Project Lead",
      new Person("Janet", "Planner", "The Burbs"));
    if(staff.positionAvailable("Software Engineer"))
      staff.fillPosition("Software Engineer",
        new Person("Bob", "Coder", "Bright Light City"));
    System.out.println(staff);
  }
}

如果用接口取代具体类,那么就可以使用DynamicProxy来自动创建空对象,代码如下:

1、操作命令类:

public interface Operation {
  String description();
  void command();
} ///:~

2、Rebot接口:

public interface Robot {
  String name();
  String model();
  List<Operation> operations(); 
}

3、SnowRemovalRobot扫雪机器人实现类

import java.util.*;


public class SnowRemovalRobot implements Robot {
  private String name;
  public SnowRemovalRobot(String name) {this.name = name;}
  public String name() { return name; }
  public String model() { return "SnowBot Series 11"; }
  public List<Operation> operations() {
    return Arrays.asList(
      new Operation() {
        public String description() {
          return name + " can shovel snow";
        }
        public void command() {
          System.out.println(name + " shoveling snow");
        }
      },
      new Operation() {
        public String description() {
          return name + " can chip ice";
        }
        public void command() {
          System.out.println(name + " chipping ice");
        }
      }
    );
  }

4:空机器人代理处理器:

class NullRobotProxyHandler implements InvocationHandler {
  private String nullName;
  private Robot proxied = new NRobot();
  NullRobotProxyHandler(Class<? extends Robot> type) {
    nullName = type.getSimpleName() + " NullRobot";
  }
  private class NRobot implements Null, Robot {
    public String name() { return nullName; }
    public String model() { return nullName; }
    public List<Operation> operations() {
      return Collections.emptyList();
    }
  }
  public Object
  invoke(Object proxy, Method method, Object[] args)
  throws Throwable {
    return method.invoke(proxied, args);
  }
}

5:测试类:

public class NullRobot {
 
  public static Robot
  newNullRobot(Class<? extends Robot> type) {
    return (Robot)Proxy.newProxyInstance(
      NullRobot.class.getClassLoader(),
      new Class[]{ Null.class, Robot.class },
      new NullRobotProxyHandler(type));
  }
  public static void test(Robot r) {
      if(r instanceof Null)
        System.out.println("[Null Robot]");
      System.out.println("Robot name: " + r.name());
      System.out.println("Robot model: " + r.model());
      for(Operation operation : r.operations()) {
        System.out.println(operation.description());
        operation.command();
      }
    }
  public static void main(String[] args) {
      Robot[] bots = {
        new SnowRemovalRobot("SnowBee"),
        newNullRobot(SnowRemovalRobot.class)
      };
      for(Robot bot : bots)
        Test.test(bot);
    }



---------------------------------------------------------接口与类型信息------------------------------------------------------------------


所以通过instanceof强制转换还是会访问到子类的方法,所以这种耦合性的话,还是会传播出去


通过反射可以访问任何方法和属性,没有权限可以拦截,具体例子:

1、interface A {
 void f();
}

2、class InnerA {
  private static class C implements A {
    public void f() { print("public C.f()"); }
    public void g() { print("public C.g()"); }
    void u() { print("package C.u()"); }
    protected void v() { print("protected C.v()"); }
    private void w() { print("private C.w()"); }
  }
  public static A makeA() { return new C(); }
}


3、public class InnerImplementation {

  static void callHiddenMethod(Object a, String methodName)
 throws Exception {
   
Method g = a.getClass().getDeclaredMethod(methodName);
   g.setAccessible(true);

   g.invoke(a);
  }

  public static void main(String[] args) throws Exception {
    A a = InnerA.makeA();
    a.f();
    System.out.println(a.getClass().getName());
    // Reflection still gets into the private class:
    callHiddenMethod(a, "g");
    callHiddenMethod(a, "u");
    callHiddenMethod(a, "v");
    callHiddenMethod(a, "w");
  }
  
  
}

---------------------------------------------总结-------------------------------


0 0
原创粉丝点击