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

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

  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反编译。但是反射也带来它的好处。在类中留下后门这一事实,也许可以让你解决某些特定的问题。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 多态 任何域的访问操作都将有编译器解析,如果某个方法是静态的,它的行为就不具有多态性 java默认对象的销毁顺序与...
    yueyue_projects阅读 936评论 0 1
  • Java经典问题算法大全 /*【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子...
    赵宇_阿特奇阅读 1,852评论 0 2
  • 最近内心有些空虚就在百度里搜一些正能量的美剧,而备受推荐的就是《肖申克的救赎》,既然人都这么火了,岂有不看的道理?...
    小运阅读 438评论 0 0