Java基础加强 (二)

2014-11-24 09:56:18 · 作者: · 浏览: 4
础班的时候 , 老师跟你说 如果你的 一个类定义了一个有参的构造函数,那么还需要在定义一个无参的构造函数.

11、Field类

(1)Field类代表某个类中的一个成员变量

(2)问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联的是哪个对象呢?所以字段fieldX 代表的是x的定义,而不是具体的x变量。(注意访问权限的问题)

(3)示例代码:

ReflectPoint point = new ReflectPoint(1,7);

Field y = Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");

System.out.println(y.get(point));

//Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getField("x");

Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");

x.setAccessible(true);

System.out.println(x.get(point));

12、Method类

(1)Method类代表某个类中的一个成员方法

(2)得到类中的某一个方法:

例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);

(3)调用方法:

通常方式:System.out.println(str.charAt(1));

反射方式: System.out.println(charAt.invoke(str, 1));

如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?说明该Method对象对应的是一个静态方法!

(4)jdk1.4和jdk1.5的invoke方法的区别:

Jdk1.5:public Object invoke(Object obj,Object... args)

Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。

13、用反射方式执行某个类中的main方法

(1)目标:

写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。用普通方式调完后,大家要明白为什么要用反射方式去调啊?

(2)问题:

启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。

(3)解决办法:

mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});

mainMethod.invoke(null,(Object)new String[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了


14、内省(Introspector) — JavaBean

(1)什么是JavaBean和属性的读写方法

(2)访问JavaBean属性的两种方式:

直接调用bean的setXXX或getXXX方法。

通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式。

通过PropertyDescriptor类操作Bean的属性

通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。


15、内省—beanutils工具包

(1)Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。

(2)Beanutils工具包的常用类:

BeanUtils

PropertyUtils

ConvertUtils.regsiter(Converter convert, Class clazz)

自定义转换器

16、泛型(Generic)—泛形的作用

(1)JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:

(2)ArrayList list = new ArrayList();

list.add("abc");

Integer num = (Integer) list.get(0); //运行时会出错,但编码时发现不了

list.add(new Random());

list.add(new ArrayList());

for(int i=0;i

( )list.get(i); //此处取出来的对象应转换成什么类型

}

(3)JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。

(4)注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。

(5)泛形的基本术语,以ArrayList为例:<>念着typeof

ArrayList中的E称为类型参数变量

ArrayList中的Integer称为实际类型参数

整个称为ArrayList泛型类型

整个ArrayList称为参数化的类型ParameterizedType

17、泛型典型应用

(1)使用迭代器迭代泛形集合中的元素。

(2)使用增强for循环迭代泛形集合中的元素。