美文网首页Android面试经验笔试&&面试经验
只想把基础打好之-类型信息

只想把基础打好之-类型信息

作者: 扈扈哈嘿 | 来源:发表于2017-03-16 17:24 被阅读35次

    运行时类型信息使得你可以在程序运行时发现和使用类型信息

    1. 为什么需要RTTI(运行时类型信息):比如,我们使用```
      Interface inter=new InterfalceImp();
    为了知道这个inter到底是哪个实现类型的实例来方便做对应的操作,例如,三角形是Shape的实现类型,圆也是Shape的实现类型,那我们要针对Shape做旋转操作,这就要判断shape倒底是什么类型的对象,因为对圆做旋转操作毫无意义。
    2. Class对象:生成Class对象的引用:Class.forName("全类名")还有使用类字面量:ClassType.class。前一种会抛出异常(ClassNotFoundException),后一种不会。**当使用后一种来创建Class对象的引用时,不会自动地初始化该Class对象**,为了类的使用而做的准备工作有三个:1:加载,2:链接,3:初始化。初始化被延迟到了静态方法(构造器隐式地是静态的)或者非常数表态域进行首次引用时才执行:
    ```java
    class Initable{
        static final int staticFinal=47;
        static final int staticFinal2=ClassTest.rand.nextInt(1000);
        // static final int staticFinal2=78;
        static {
            System.out.println("Initializing Initable");
        }
    }
    class Initable2{
        static int staticNotFinal=147;
        static {
            System.out.println("Initializing Initabl2");
        }
    }
    class Initable3{
        static int staticNotFinal=74;
        static {
            System.out.println("Initializing Initabl3");
        }
    }
    public class ClassTest {
        public static Random rand=new Random(47);
        public static void main(String[] args){
         Class initable=Initable.class;
         System.out.println("After creating Initable ref");
         System.out.println(Initable.staticFinal);
         System.out.println(Initable.staticFinal2);
         System.out.println(Initable2.staticNotFinal);
    
            try {
                Class initable3=Class.forName("classtest.Initable3");
                System.out.println("After Initable3 create ref");
                System.out.println(Initable3.staticNotFinal);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    运行结果:

    After creating Initable ref
    47
    Initializing Initable
    258
    Initializing Initabl2
    147
    Initializing Initabl3
    After Initable3 create ref
    74
    

    如果一个static不是final的,那么在对它访问时,总是要求在它读取之前,首先进行链接(为这个域分配存储空间)和初始化(初始该存储空间)。

    1. cast()转型:
    interface Building{}
    class House implements Building{}
    public class ClassTest {
        public static void main(String[] args){
             Building building=new House();
             Class<House>  houseType=House.class;
             House house=houseType.cast(building);
             //或者也可以这样
            house=(House) building;
        }
    }
    

    cast方法接受参数对象,它与上面main方法最后一行相比,做了很多额外的工作 。新的转型语法对于无法使用普通转型的情况显得非常有用,在你编写泛型代码时,如果你存储了Class引用,并希望以后通过这个引用来执行转型,这种情况就会发生。不过很少有用到,在JAVA SE5中另一个没有任何用处的新特性就是Class.asSubclass()。该方法允许你将一个对象转型为一个更具体的对象。

    1. 动态的instanceof:Class.isInstance方法提供了一种动态地测试对象途径。instanceof与isInstance保持了类型的概念,它指的是"你是这个类吗或是你是这个类的派生类吗?",而如果用==比较实际的Class对象,就没有考虑继承-它是不是影视个确切的类型。
      5.动态代理:代理是基本的设计模式之一,它是你为了提供额外的或不同操作,而插入的用来代替"实际"对象的对象。Java的动态代理比代理的思想更近一步,因为它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理所做的调用都会被重定向到单一的调用处理器上。
    interface Interface{
        void doSomething();
        void somethineElse(String string);
    }
    class DynamicProxyHandler implements InvocationHandler{
        private Object proxied;
        public DynamicProxyHandler(Object proxied){
            this.proxied=proxied;
        }
    
        @Override
        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  RealObject implements Interface{
    
        @Override
        public void doSomething() {
            System.out.println("realobject doSomething");
        }
    
        @Override
        public void somethineElse(String string) {
    System.out.println("realobject somethingelse:"+string);
        }
    }
    class SimpleDynamicProxy{
        public static void consumer(Interface iface){
            iface.doSomething();
            iface.somethineElse("kwkw");
        }
    }
    public class ClassTest {
        public static void main(String[] args){
    RealObject real=new RealObject();
    SimpleDynamicProxy.consumer(real);
    Interface inter= (Interface) Proxy.newProxyInstance(
            Interface.class.getClassLoader(),new Class[]{Interface.class},new DynamicProxyHandler(real)
    );
    SimpleDynamicProxy.consumer(inter);
        }
    }
    

    运行结果:

    realobject doSomething
    realobject somethingelse:kwkw
    *** proxy:class classtest.$Proxy0.method:public abstract void classtest.Interface.doSomething().args:null
    realobject doSomething
    *** proxy:class classtest.$Proxy0.method:public abstract void classtest.Interface.somethineElse(java.lang.String).args:[Ljava.lang.Object;@4dc63996
     kwkw
    realobject somethingelse:kwkw
    

    可以通过静态方法Proxy.newProxyInstance可以创建动态代理。

    1. 空对象:当使用内置的null表示缺少对象时,这显得枯燥。问题在于null除了在你试图用它执行任何操作来产生NullPointerException之外,它自己没有任何用处。你可以假设所有对象都是有效的,而不必浪费编程精力支检查null。
     interface Null{}
     class Person{
         public final String first;
         public final String second;
         public final String address;
         public Person(String first,String second,String address){
             this.first=first;
             this.second=second;
             this.address=address;
         }
         public static class NullPerson extends Person implements Null{
             private NullPerson(){
                 super("None","None","None");
             }
    
         }
         public static final Person NULL=new NullPerson();
     }
    

    你就可以使用Person.NULL来表示Person的空对象。也可以用Person.NULL来判断空对象了。空对象的逻辑变体是模拟对象与桩。但是模拟对象与桩都只是假扮可以传递实际信息的存活对象,而不是像空对象那样可以成为null更加智能化的替代物。

    1. 接口与类型信息:当我们用B继承A接口时,并不希望在使用"A a=new B()"初始a之后再将a向下转型为B的对象实体,这个时候你需要将限定的B的访问控制符,使得在访问控制以外的地方不能访问B,再提供一个public的初始化B的地方。但是我们通过反射任然可以访问这个B的信息。即使我们发布编译之后的文件,任然可以使用JDK自带的javap反编译。但是反射也带来它的好处。在类中留下后门这一事实,也许可以让你解决某些特定的问题。

    相关文章

      网友评论

        本文标题:只想把基础打好之-类型信息

        本文链接:https://www.haomeiwen.com/subject/dakxnttx.html