一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Java網(wǎng)絡(luò)編程精解之Java語言的反射機制二

 dengxianzhi 2011-04-13

    10.3  代理模式

    代理模式是常用的Java設(shè)計模式,它的特征是代理類與委托類有同樣的接口,如圖10-2所示。代理類主要負責為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會存在關(guān)聯(lián)關(guān)系,一個代理類的對象與一個委托類的對象關(guān)聯(lián),代理類的對象本身并不真正實現(xiàn)服務(wù),而是通過調(diào)用委托類的對象的相關(guān)方法,來提供特定的服務(wù)。

     

    圖10-2  代理模式

    按照代理類的創(chuàng)建時期,代理類可分為兩種。

    ◆靜態(tài)代理類:由程序員創(chuàng)建或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經(jīng)存在了。

    ◆動態(tài)代理類:在程序運行時,運用反射機制動態(tài)創(chuàng)建而成。

    10.3.1  靜態(tài)代理類

    如圖10-3所示,HelloServiceProxy類(如例程10-13所示)是代理類,HelloServiceImpl類(如例程10-12所示)是委托類,這兩個類都實現(xiàn)了HelloService接口(如例程10-11所示)。其中HelloServiceImpl類是HelloService接口的真正實現(xiàn)者,而HelloServiceProxy類是通過調(diào)用HelloServiceImpl類的相關(guān)方法來提供特定服務(wù)的。HelloServiceProxy類的echo()方法和getTime()方法會分別調(diào)用被代理的HelloServiceImpl對象的echo()方法和getTime()方法,并且在方法調(diào)用前后都會執(zhí)行一些簡單的打印操作。由此可見,代理類可以為委托類預(yù)處理消息、把消息轉(zhuǎn)發(fā)給委托類和事后處理消息等。

     

    圖10-3  HelloServiceProxy類是HelloService的代理類

    例程10-11  HelloService.java

    package proxy;
    import java.util.Date;
    public interface HelloService{
    public String echo(String msg);
    public Date getTime();
    }

    例程10-12  HelloServiceImpl.java

    package proxy;
    import java.util.Date;
    public class HelloServiceImpl implements HelloService{
    public String echo(String msg){
    return "echo:"+msg;
    }
    public Date getTime(){
    return new Date();
    }
    }

    例程10-13  HelloServiceProxy.java

    package proxy;
    import java.util.Date;
    public class HelloServiceProxy implements HelloService{
    private HelloService helloService;     //表示被代理的HelloService實例

    public HelloServiceProxy(HelloService helloService){
    this.helloService=helloService;
    }

    public void setHelloServiceProxy(HelloService helloService){
    this.helloService=helloService;
    }

    public String echo(String msg){
    System.out.println("before calling echo()");   //預(yù)處理
    String result=helloService.echo(msg);    //調(diào)用被代理的HelloService實例的echo()方法
    System.out.println("after calling echo()");   //事后處理
    return result;
    }
    public Date getTime(){
    System.out.println("before calling getTime()");   //預(yù)處理
    Date date=helloService.getTime();    //調(diào)用被代理的HelloService實例的getTime()方法
    System.out.println("after calling getTime()");   //事后處理
    return date;
    }
    }

    在Client1類(如例程10-14所示)的main()方法中,先創(chuàng)建了一個HelloServiceImpl對象,又創(chuàng)建了一個HelloServiceProxy對象,最后調(diào)用HelloServiceProxy對象的echo()方法。

      例程10-14  Client1.java

      package proxy;
      public class Client1{
      public static void main(String args[]){
      HelloService helloService=new HelloServiceImpl();
      HelloService helloServiceProxy=new HelloServiceProxy(helloService);
      System.out.println(helloServiceProxy.echo("hello"));
      }
      }

      運行Client1類,打印結(jié)果如下:

      before calling echo()
      after calling echo()
      echo:hello

      如圖10-4所示顯示了Client1調(diào)用HelloServiceProxy類的echo()方法的時序圖。

       

      圖10-4  Client1調(diào)用HelloServiceProxy類的echo()方法的時序圖

      例程10-13的HelloServiceProxy類的源代碼是由程序員編寫的,在程序運行前,它的.class文件就已經(jīng)存在了,這種代理類稱為靜態(tài)代理類。

      10.3.2  動態(tài)代理類

      與靜態(tài)代理類對照的是動態(tài)代理類,動態(tài)代理類的字節(jié)碼在程序運行時由Java反射機制動態(tài)生成,無需程序員手工編寫它的源代碼。動態(tài)代理類不僅簡化了編程工作,而且提高了軟件系統(tǒng)的可擴展性,因為Java反射機制可以生成任意類型的動態(tài)代理類。java.lang.reflect包中的Proxy類和InvocationHandler接口提供了生成動態(tài)代理類的能力。

      Proxy類提供了創(chuàng)建動態(tài)代理類及其實例的靜態(tài)方法。

      (1)getProxyClass()靜態(tài)方法負責創(chuàng)建動態(tài)代理類,它的完整定義如下:

      public static Class getProxyClass(ClassLoader loader, Class[] interfaces)
      throws IllegalArgumentException

      參數(shù)loader指定動態(tài)代理類的類加載器,參數(shù)interfaces指定動態(tài)代理類需要實現(xiàn)的所有接口。

      (2)newProxyInstance()靜態(tài)方法負責創(chuàng)建動態(tài)代理類的實例,它的完整定義如下:

      public static Object newProxyInstance(ClassLoader loader, Class[] interfaces,
      InvocationHandler handler) throws IllegalArgumentException

      參數(shù)loader指定動態(tài)代理類的類加載器,參數(shù)interfaces指定動態(tài)代理類需要實現(xiàn)的所有接口,參數(shù)handler指定與動態(tài)代理類關(guān)聯(lián)的 InvocationHandler對象。

      以下兩種方式都創(chuàng)建了實現(xiàn)Foo接口的動態(tài)代理類的實例:

      /****  方式一  ****/
      //創(chuàng)建InvocationHandler對象
      InvocationHandler handler = new MyInvocationHandler(...);
      //創(chuàng)建動態(tài)代理類
      Class proxyClass = Proxy.getProxyClass(
      Foo.class.getClassLoader(), new Class[] { Foo.class });
      //創(chuàng)建動態(tài)代理類的實例
      Foo foo = (Foo) proxyClass.
      getConstructor(new Class[] { InvocationHandler.class }).
      newInstance(new Object[] { handler });

      /****  方式二  ****/
      //創(chuàng)建InvocationHandler對象
      InvocationHandler handler = new MyInvocationHandler(...);
      //直接創(chuàng)建動態(tài)代理類的實例
      Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
      new Class[] { Foo.class },
      handler);

      由Proxy類的靜態(tài)方法創(chuàng)建的動態(tài)代理類具有以下特點:

      ◆動態(tài)代理類是public、final和非抽象類型的;
      ◆動態(tài)代理類繼承了java.lang.reflect.Proxy類; 
      ◆動態(tài)代理類的名字以“$Proxy”開頭;
      ◆動態(tài)代理類實現(xiàn)getProxyClass()和newProxyInstance()方法中參數(shù)interfaces指定的所有接口; 
      ◆Proxy類的isProxyClass(Class cl)靜態(tài)方法可用來判斷參數(shù)指定的類是否為動態(tài)代理類。只有通過Proxy類創(chuàng)建的類才是動態(tài)代理類;
      ◆動態(tài)代理類都具有一個public類型的構(gòu)造方法,該構(gòu)造方法有一個InvocationHandler類型的參數(shù)。

        由Proxy類的靜態(tài)方法創(chuàng)建的動態(tài)代理類的實例具有以下特點:

        ◆假定變量foo是一個動態(tài)代理類的實例,并且這個動態(tài)代理類實現(xiàn)了Foo接口,那么“foo instanceof Foo”的值為true。把變量foo強制轉(zhuǎn)換為Foo類型是合法的:

        (Foo) foo   //合法

        ◆每個動態(tài)代理類實例都和一個InvocationHandler實例關(guān)聯(lián)。Proxy類的getInvocationHandler(Object proxy)靜態(tài)方法返回與參數(shù)proxy指定的代理類實例所關(guān)聯(lián)的InvocationHandler對象。
        ◆假定Foo接口有一個amethod()方法,那么當程序調(diào)用動態(tài)代理類實例foo的amethod()方法時,該方法會調(diào)用與它關(guān)聯(lián)的InvocationHandler對象的invoke()方法。

        InvocationHandler接口為方法調(diào)用接口,它聲明了負責調(diào)用任意一個方法的invoke()方法:

        Object invoke(Object proxy,Method method,Object[] args) throws Throwable

        參數(shù)proxy指定動態(tài)代理類實例,參數(shù)method指定被調(diào)用的方法,參數(shù)args指定向被調(diào)用方法傳遞的參數(shù),invoke()方法的返回值表示被調(diào)用方法的返回值。

        如圖10-5所示,HelloServiceProxyFactory類(如例程10-15所示)的getHello- ServiceProxy()靜態(tài)方法負責創(chuàng)建實現(xiàn)了HelloService接口的動態(tài)代理類的實例。

         

        圖10-5  HelloServiceProxyFactory類創(chuàng)建動態(tài)代理類實例

        例程10-15  HelloServiceProxyFactory.java

        package proxy;
        import java.lang.reflect.*;
        public class HelloServiceProxyFactory {
        /** 創(chuàng)建一個實現(xiàn)了HelloService接口的動態(tài)代理類的實例
        *  參數(shù)helloService引用被代理的HelloService實例
        */ 
        public static HelloService getHelloServiceProxy(final HelloService helloService){
        //創(chuàng)建一個實現(xiàn)了InvocationHandler接口的匿名類的實例
        InvocationHandler handler=new InvocationHandler(){
        public Object invoke(Object proxy,Method method,Object args[])throws Exception{
        System.out.println("before calling "+method);    //預(yù)處理
        Object result=method.invoke(helloService,args);
        //調(diào)用被代理的HelloService實例的方法
        System.out.println("after calling "+method);    //事后處理
        return result;
        }
        };

        Class classType=HelloService.class;
        return (HelloService)Proxy.newProxyInstance(classType.getClassLoader(),
        new Class[]{classType},
        handler);
        }//# getHelloServiceProxy()
        }

        如例程10-16所示的Client2類先創(chuàng)建了一個HelloServiceImpl實例,然后創(chuàng)建了一個動態(tài)代理類實例helloServiceProxy,最后調(diào)用動態(tài)代理類實例的echo()方法。

        例程10-16  Client2.java

        package proxy;
        public class Client2{
        public static void main(String args[]){
        HelloService helloService=new HelloServiceImpl();
        HelloService helloServiceProxy=
        HelloServiceProxyFactory.getHelloServiceProxy(helloService);
        System.out.println("動態(tài)代理類的名字為"
        +helloServiceProxy.getClass().getName());
        System.out.println(helloServiceProxy.echo("Hello"));
        }
        }

        運行Client2,打印結(jié)果如下:

        動態(tài)代理類的名字為$Proxy0
        before calling public abstract java.lang.
        String proxy.HelloService.echo(java.lang.String)
        after calling public abstract java.lang.
        String proxy.HelloService.echo(java.lang.String)
        echo:Hello

        從以上打印結(jié)果看出,動態(tài)代理類的名字為$Proxy0。如圖10-6所示顯示了Client2調(diào)用動態(tài)代理類$Proxy0的實例helloServiceProxy的echo()方法的時序圖。

         

        圖10-6  Client2調(diào)用動態(tài)代理類$Proxy0的echo()方法的時序圖

          10.3.3  在遠程方法調(diào)用中運用代理類

          如圖10-7所示,SimpleClient客戶端通過HelloService代理類來調(diào)用SimpleServer服務(wù)器端的HelloServiceImpl對象的方法??蛻舳说腍elloService代理類也實現(xiàn)了HelloService接口,這可以簡化SimpleClient客戶端的編程。對于SimpleClient客戶端而言,與遠程服務(wù)器的通信的細節(jié)被封裝到HelloService代理類中。SimpleClient客戶端可以按照以下方式調(diào)用遠程服務(wù)器上的HelloServiceImpl對象的方法:

          //創(chuàng)建HelloService代理類的對象
          HelloService helloService1=new HelloServiceProxy(connector);
          //通過代理類調(diào)用遠程服務(wù)器上的HelloServiceImpl對象的方法
          System.out.println(helloService1.echo("hello"));

          從以上程序代碼可以看出,SimpleClient客戶端調(diào)用遠程對象的方法的代碼與調(diào)用本地對象的方法的代碼很相似,由此可以看出,代理類簡化了客戶端的編程。

           

          圖10-7  SimpleClient通過HelloService代理類調(diào)用遠程對象的方法

          Connector類負責建立與遠程服務(wù)器的連接,以及接收和發(fā)送Socket對象。如例程10-17所示是Connector類的源程序。

          例程10-17  Connector.java

          package proxy1;
          import java.io.*;
          import java.net.*;
          import java.util.*;
          public class Connector {
          private String host;
          private int port;
          private Socket skt;
          private InputStream is;
          private ObjectInputStream ois;
          private OutputStream os;
          private ObjectOutputStream oos;

          public Connector(String host,int port)throws Exception{
          this.host=host;
          this.port=port;
          connect(host,port);
          }

          public void send(Object obj)throws Exception{     //發(fā)送對象
          oos.writeObject(obj);
          }
          public Object receive() throws Exception{      //接收對象
          return ois.readObject();
          }
          public void connect()throws Exception{      //建立與遠程服務(wù)器的連接
          connect(host,port);
          }
          public void connect(String host,int port)throws Exception{    //建立與遠程服務(wù)器的連接
          skt=new Socket(host,port);
          os=skt.getOutputStream();
          oos=new ObjectOutputStream(os);
          is=skt.getInputStream();
          ois=new ObjectInputStream(is);
          }
          public void close(){        //關(guān)閉連接
          try{
          }finally{
          try{
          ois.close();
          oos.close();
          skt.close();
          }catch(Exception e){
          System.out.println("Connector.close: "+e);
          }
          }
          }
          }

          HelloService代理類有兩種創(chuàng)建方式:一種方式是創(chuàng)建一個HelloServiceProxy靜態(tài)代理類,如例程10-18所示;還有一種方式是創(chuàng)建HelloService的動態(tài)代理類,如例程10-19所示ProxyFactory類的靜態(tài)getProxy()方法就負責創(chuàng)建HelloService的動態(tài)代理類,并且返回它的一個實例。

          例程10-18  HelloServiceProxy.java(靜態(tài)代理類)

          package proxy1;
          import java.util.Date;
          public class HelloServiceProxy implements HelloService{
          private String host;
          private int port;

          public HelloServiceProxy(String host,int port){
          this.host=host;
          this.port=port;
          }
          public String echo(String msg)throws RemoteException{
          Connector connector=null;
          try{
          connector=new Connector(host,port);
          Call call=new Call("proxy1.HelloService","echo",
          new Class[]{String.class},new Object[]{msg});
          connector.send(call);
          call=(Call)connector.receive();
          Object result=call.getResult();
          if(result instanceof Throwable)
          throw new RemoteException((Throwable)result);    //把異常都轉(zhuǎn)換為RemoteException
          else
          return (String)result;
          }catch(Exception e){
          throw new RemoteException(e);     //把異常都轉(zhuǎn)換為RemoteException
          }finally{if(connector!=null)connector.close();}
          }

          public Date getTime()throws RemoteException{
          Connector connector=null;
          try{
          connector=new Connector(host,port);
          Call call=new Call("proxy1.HelloService","getTime",new Class[]{},new Object[]{});
          connector.send(call);
          call=(Call)connector.receive();
          Object result=call.getResult();
          if(result instanceof Throwable)
          throw new RemoteException((Throwable)result);  //把異常都轉(zhuǎn)換為RemoteException
          else
          return (Date)result;
          }catch(Exception e){
          throw new RemoteException(e);      //把異常都轉(zhuǎn)換為RemoteException
          }finally{if(connector!=null)connector.close();}
          }
          }

            例程10-19  ProxyFactory.java(負責創(chuàng)建動態(tài)代理類及其實例)

            package proxy1;
            import java.lang.reflect.*;
            public class ProxyFactory {
            public static Object getProxy(final Class classType,final String host,final int port){
            InvocationHandler handler=new InvocationHandler(){
            public Object invoke(Object proxy,Method method,Object args[])
            throws Exception{
            Connector connector=null;
            try{
            connector=new Connector(host,port);
            Call call=new Call(classType.getName(),
            method.getName(),method.getParameterTypes(),args);
            connector.send(call);
            call=(Call)connector.receive();
            Object result=call.getResult();
            if(result instanceof Throwable)
            throw new RemoteException((Throwable)result);  //把異常都轉(zhuǎn)換為RemoteException
            else
            return result;
            }finally{if(connector!=null)connector.close();}
            }
            };

            return Proxy.newProxyInstance(classType.getClassLoader(),
            new Class[]{classType},
            handler);
            }
            }

            無論HelloService的靜態(tài)代理類還是動態(tài)代理類,都通過Connector類來發(fā)送和接收Call對象。ProxyFactory工廠類的getProxy()方法的第一個參數(shù)classType指定代理類實現(xiàn)的接口的類型,如果參數(shù)classType的取值為HelloService.class,那么getProxy()方法就創(chuàng)建HelloService動態(tài)代理類的實例。如果參數(shù)classType的取值為Foo.class,那么getProxy()方法就創(chuàng)建Foo動態(tài)代理類的實例。由此可見,getProxy()方法可以創(chuàng)建任意類型的動態(tài)代理類的實例,并且它們都具有調(diào)用被代理的遠程對象的方法的能力。

            如果使用靜態(tài)代理方式,那么對于每一個需要代理的類,都要手工編寫靜態(tài)代理類的源代碼;如果使用動態(tài)代理方式,那么只要編寫一個動態(tài)代理工廠類,它就能自動創(chuàng)建各種類型的動態(tài)代理類,從而大大簡化了編程,并且提高了軟件系統(tǒng)的可擴展性和可維護性。

            如例程10-20所示的SimpleClient類的main()方法中,分別通過靜態(tài)代理類和動態(tài)代理類去訪問SimpleServer服務(wù)器上的HelloServiceImpl對象的各種方法。

            例程10-20  SimpleClient.java

            package proxy1;
            import java.io.*;
            import java.net.*;
            import java.util.*;

            public class SimpleClient {
            public static void main(String args[])throws Exception {
            //創(chuàng)建靜態(tài)代理類實例
            HelloService helloService1=new HelloServiceProxy("localhost",8000);
            System.out.println(helloService1.echo("hello"));
            System.out.println(helloService1.getTime());

            //創(chuàng)建動態(tài)代理類實例
            HelloService helloService2=
            (HelloService)ProxyFactory.getProxy(HelloService.class,"localhost",8000);
            System.out.println(helloService2.echo("hello"));
            System.out.println(helloService2.getTime());
            }
            }

            先運行命令“java proxy1.SimpleServer”,再運行命令“java proxy1.SimpleClient”,SimpleClient端的打印結(jié)果如下:

            echo:hello
            Thu Nov 02 10:54:48 CST 2006
            echo:hello
            Thu Nov 02 10:54:49 CST 2006

            proxy1.SimpleServer類的源程序與本章10.2節(jié)的例程10-9的remotecall.Simple- Server類相同。如圖10-8和圖10-9所示分別顯示了SimpleClient通過HelloService靜態(tài)代理類和動態(tài)代理類訪問遠程HelloServiceImpl對象的echo()方法的時序圖。

             

            圖10-8  SimpleClient通過HelloService靜態(tài)代理類(HelloServiceProxy)訪問遠程對象的方法的時序圖

             

            圖10-9  SimpleClient通過HelloService動態(tài)代理類($Proxy0)訪問遠程對象的方法的時序圖

              10.4  小結(jié)

              Java反射機制是Java語言的一個重要特性??紤]實現(xiàn)一個newInstance(String className)方法,它的作用是根據(jù)參數(shù)className指定的類名,通過該類的不帶參數(shù)的構(gòu)造方法創(chuàng)建這個類的對象,并將其返回。如果不運用Java反射機制,必須在newInstance()方法中羅列參數(shù)className所有可能的取值,然后創(chuàng)建相應(yīng)的對象:

              public Object newInstance(String className) throws Exception{
              if(className.equals("HelloService1"))
              return new HelloService1();
              if(className.equals("HelloService2"))
              return new HelloService2();
              if(className.equals("HelloService3"))
              return new HelloService3();
              if(className.equals("HelloService4"))
              return new HelloService4();
              ...
              if(className.equals("HelloService1000"))
              return new HelloService1000();
              }

              以上程序代碼很冗長,而且可維護性差。如果在以后軟件的升級版本中去除了一個HelloService4類,或者增加了一個HelloService1001類,都需要修改以上newInstance()方法。

              如果運用反射機制,就可以簡化程序代碼,并且提高軟件系統(tǒng)的可維護性和可擴展性:

              public Object newInstance(String className) throws Exception{
              Class classType=Class.forName(className);
              return classType.newInstance();
              }

              Java反射機制在服務(wù)器程序和中間件程序中得到了廣泛運用。在服務(wù)器端,往往需要根據(jù)客戶的請求,動態(tài)調(diào)用某一個對象的特定方法。此外,有一種ORM(Object-Relation Mapping,對象-關(guān)系映射)中間件能夠把任意一個JavaBean持久化到關(guān)系數(shù)據(jù)庫中。在ORM中間件的實現(xiàn)中,運用Java反射機制來讀取任意一個JavaBean的所有屬性,或者給這些屬性賦值。在作者的另一本書《精通Hibernate:Java對象持久化技術(shù)詳解》中闡述了Java反射機制在Hibernate(一種ORM中間件)的實現(xiàn)中的運用。

              在JDK類庫中,主要由以下類來實現(xiàn)Java反射機制,這些類都位于java.lang.reflect包中。

              ◆Class類:代表一個類。
              ◆Field類:代表類的屬性。
              ◆Method類:代表類的方法。
              ◆Constructor類:代表類的構(gòu)造方法。
              ◆Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組元素的靜態(tài)方法。
              ◆Proxy類和InvocationHandler接口:提供了生成動態(tài)代理類及其實例的方法。

              本章還介紹了Java反射機制、靜態(tài)代理模式和動態(tài)代理模式在遠程方法調(diào)用中的運用。本章以SimpleClient客戶調(diào)用SimpleServer服務(wù)器上的HelloServiceImpl對象的方法為例,探討了實現(xiàn)遠程方法調(diào)用的一些技巧。本書第11章介紹的RMI框架是JDK類庫提供的一個現(xiàn)成的完善的遠程方法調(diào)用框架。即使程序員不了解這個框架本身的實現(xiàn)細節(jié),也能使用這個框架。不過,熟悉框架本身的實現(xiàn)原理,可以幫助程序員更嫻熟地運用RMI框架。本章對實現(xiàn)遠程方法調(diào)用所作的初步探討,有助于程序員去進一步探索RMI框架本身的實現(xiàn)原理。

              10.5  練習題

              1.假定Tester類有如下test方法:

              public int test(int p1, Integer p2)

              以下哪段代碼能正確地動態(tài)調(diào)用一個Tester對象的test方法?(單選)

              A.

              Class classType=Tester.class;
              Object tester=classType.newInstance();
              Method addMethod=classType.getMethod("test",new Class[]{int.class,int.class});
              Object result=addMethod.invoke(tester,
              new Object[]{new Integer(100),new Integer(200)});

              B.

              Class classType=Tester.class;
              Object tester=classType.newInstance();
              Method addMethod=classType.getMethod("test",new Class[]{int.class,int.class});
              int result=addMethod.invoke(tester,
              new Object[]{new Integer(100),new Integer(200)});


              C.

              Class classType=Tester.class;
              Object tester=classType.newInstance();
              Method addMethod=classType.getMethod("test",new Class[]{int.class,Integer.class});
              Object result=addMethod.invoke(tester,
              new Object[]{new Integer(100),new Integer(200)});

              D.

              Class classType=Tester.class;
              Object tester=classType.newInstance();
              Method addMethod=classType.getMethod("test",new Class[]{int.class,Integer.class});
              Integer result=addMethod.invoke(tester,
              new Object[]{new Integer(100),new Integer(200)});


              2.以下哪些方法在Class類中定義?(多選)

              A.getConstructors()  B.getPrivateMethods() C.getDeclaredFields()
              D.getImports()   E.setField()

              3.以下哪些說法正確?(多選)

              A.動態(tài)代理類與靜態(tài)代理類一樣,必須由開發(fā)人員編寫源代碼,并編譯成.class文件
              B.代理類與被代理類具有同樣的接口
              C.java.lang.Exception類實現(xiàn)了java.io.Serializable接口,因此Exception對象可以被序列化后在網(wǎng)絡(luò)上傳輸
              D.java.lang.reflect包中的Proxy類提供了創(chuàng)建動態(tài)代理類的方法

              4.以下哪些屬于動態(tài)代理類的特點?(多選)

              A.動態(tài)代理類是public、final和非抽象類型的
              B.動態(tài)代理類繼承了java.lang.reflect.Proxy類 
              C.動態(tài)代理類實現(xiàn)了getProxyClass()或newProxyInstance()方法中參數(shù)interfaces指定的所有接口 
              D.動態(tài)代理類可以繼承用戶自定義的任意類 
              E.動態(tài)代理類都具有一個public類型的構(gòu)造方法,該構(gòu)造方法有一個InvocationHandler類型的參數(shù)

              5.在本章10.3.3節(jié)(在遠程方法調(diào)用中運用代理類)介紹的例子中,Connector類位于服務(wù)器端還是客戶端?(單選)

              A.服務(wù)器端     B.客戶端

              6.在本章10.3.3節(jié)(在遠程方法調(diào)用中運用代理類)介紹的例子中,HelloServiceProxy類位于服務(wù)器端還是客戶端?(單選)

              A.服務(wù)器端     B.客戶端

              7.運用本章介紹的動態(tài)代理機制,重新實現(xiàn)第1章的EchoServer服務(wù)器與EchoClient客戶,具體實現(xiàn)方式參照本章10.3.3節(jié)(在遠程方法調(diào)用中運用代理類)所介紹的例子。

              答案:1.C 2.AC 3.BCD  4.ABCE  5.B  6.B

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲欧美视频欧美视频| 在线观看欧美视频一区| 欧美日韩综合在线第一页| 日韩欧美三级中文字幕| 好吊色免费在线观看视频| 精品国产亚洲免费91| 少妇福利视频一区二区| 中文字幕91在线观看| 日韩精品少妇人妻一区二区| 日本熟女中文字幕一区| 国产精品免费福利在线| 国产免费成人激情视频| 久久这里只有精品中文字幕| 成年男女午夜久久久精品| 国产欧美韩日一区二区三区| 亚洲最大福利在线观看| 国产精品国产亚洲区久久| 亚洲欧美日韩综合在线成成| 亚洲二区欧美一区二区| 亚洲精品一区二区三区免| 久久黄片免费播放大全| 国产真人无遮挡免费视频一区| 国产麻豆成人精品区在线观看| 亚洲日本韩国一区二区三区| 亚洲国产香蕉视频在线观看| 久热久热精品视频在线观看| 黄片免费观看一区二区| 国产麻豆成人精品区在线观看| 欧美精品日韩精品一区| 国产午夜免费在线视频| 亚洲一区二区三区有码| 国产一区二区三区av在线| 日本一本在线免费福利| 人妻少妇久久中文字幕久久| 欧美日韩在线视频一区| 成人亚洲国产精品一区不卡| 后入美臀少妇一区二区| 国产精品国三级国产专不卡| 日韩免费成人福利在线| 国产成人精品一区二区在线看| 熟女乱一区二区三区丝袜|