java学习(二)-内部类+类型信息

内部类

内部类看起来就是一种代码隐藏机制,将类置于其他类的内部,它能够在运行时秘密的去捕获一个指向外围类的 引用。看了thinking in java中内部类这章,我还是没有完全理解作者所说的内部类之“非常有用的特性”,还有待 在以后的实践中去体会。下面就来聊一聊内部类之我见:

  • 首先申明内部类很简单,就是在一个外部类的作用域内定义一个类,但是创建内部类的对象必须得先有一个外 部类的对象,同时内部类拥有其外部类的所有元素的访问权。你可能会这样理解,内部类就是外部类的一个元素 ,在外部类的作用域内自然什么都能访问,但是实际情况是内部类和外部类是相对独立的两个类,当某个外部类对 象创建了一个内部类对象时,它必定会秘密地捕获一个指向那个外围类对象的应用。

  • 当你需要显示地生成对外部类对象的引用时,就必须使用this关键字,使用方法:OutObject.this,当需要 创建内部类对象时也得注意语法:OutObject.new InnerObject()。当时当你创建的是静态内部类对象的时候, 就不需要借助外部类了,这就是嵌套类。

  • 内部类可以向上转型为基类,特别是继承一个接口的时候,它能使这个接口的实现变得完全不可见,这种设计 的妙处估计是给语言的设计者们用的。这里作者给了我们一个提醒:在使用一个接口的时候你必须了解它,不然优 先考虑类的继承。

  • 用内部类可以实现“多重继承”,由于java中一个类只能继承自一个普通类,而接口没有这种限制,这个很好理 解,即让内部类继承自另一个基类,然后两个类配合着实现c++中多重继承的效果,但是在使用时需要更仔细的斟酌

  • 闭包,是我认为内部类最有用的一个特性。它能够记住在初始化内部类的时候的外部类的状态,即使外部的状 态发生了变化,它也不会失去任何信息,这样我们就可以在这个保存的状态中传入对象并执行代码,思考:在什么 情况下实现闭包,它能与类的继承起相同的作用吗?

相比于前面的几章,内部类是比较难以理解的,当然想用好它还得多思考,多练习。内部类在java GUI的控制框架 编程中能大显神威,待续···

java的类型

java在运行时识别对象和类的信息主要有两种方式:RTTI与反射。传统的RTTI是我们在编译时就已经知道了所有 的类型信息,运行时直接去调即可,而反射是处理我们在编译时不知道的类,在运行时去发现和使用类的信息。如 果对于java的类型不能有一个很好的把握,想编写出良好的程序几乎是不可能的,我们编写面向对象程序的基本目 的就是让代码只操纵对基类的应用(多态),可见在编码过程中得对类型有个很好的把握。

  • 没编写完一个新类,经过编译后就会产生一个该类的Class对象,即被保存在同名的.class文件中。当程序创建 第一个对象的静态成员的应用时,这个类就会被动态地加载到JVM中,当然构造器也是静态方法,所以new操作符会 导致类的加载。可见static初始化是在加载的时候进行的。

  • 得到一个对某个类或对象的Class对象的引用有两种方式:

    1. Class.forname("objectname") ,其中的objectname在包外时要使用全限定名
    2. onject.class。

上述两种方式的区别是第一种方法会立即导致类的加载和初始化,但是第二种方式不会引发初始化。注意上述加 载和初始化的区别,实际上类的使用分为三个过程:加载,链接(分配存储空间)和初始化,如果一个域是static final的表示是编译器常量,不需要初始化就能使用。

  • 上述两种方式的返回值类型都是Class,但是你可以保险起见在Class中使用泛型,也可以使用更灵活的Class <?>。Class类的对象可以产生类的实例,就是Class.newInstance()方法,它相当于一个虚拟的构造器,这有个限制 :使用它来创建对象,那么类必须带有默认的构造器。

  • 当进行类型的转换时,必须使用显型的转换方式,判断一个对象是不是某个类的对象时,可以有两种方式:

    1. instanceof 如:if(b instanceof Dog){},其中Dog只能是类名,不能是Class对象
    2. isInstance 如:Dog.isInstance(d),其中Dog是Class对象

上述两种方式能很好地帮你判断对象是不是属于某个类或是它的继承类,但是运用时区别何在?值得思考。

聊完了RTTI,可以来看看反射了,简单的说:

  • 对于反射机制,不能在编译时期获取.class文件,而是在运行时检查和打开.class文件。反射机制可以让你突破 类本身的访问权限,可以通过方法名和对象来使用这个类。

  • java.lang.reflect类库中包含了Method,Constructor等类,可以通过Class对象的getMethods()方法和getCon structors()方法获得类的方法和构造器。要真正地弄清楚反射机制到底是怎么实现的,JVM应该会给解释。

泛型

关于泛型真心不想看下去,所以我只摘抄了很少的常用的一些:

  1. 泛型与容器,泛型运用的最广泛的就是容器,java的一些容器的类库都是用泛型来编写的,在编写类的时候 不指定类型,在使用容器的时候再去指定类型,是不二选择。

  2. 泛型类 当一个类中要使用泛型时,需要在类名后面用尖括号将泛型括起来,在实例化对象的时候再去指定尖 括号号中的类型,注意基本类型不能使用泛型,如int必须转化为Integer才能使用泛型。

  3. 泛型方法 在定义泛型方法的时候需要在返回值之前指明泛型参数列表,用尖括号括起来。但是,需要说明一 点就是泛型类与泛型方法没有必然关系,如果在泛型类中,上述动作是不需要的,如果在非泛型类中定义泛型方法 就必须遵守上面的规则。作者写了一点指导规则:无论何时,只要你能做到,就应该尽量使用泛型方法。



Previous     Next
zhing /
Published under (CC) BY-NC-SA in categories java  tagged with java