笔记_反射

来源:互联网 发布:雪铁龙c5 知乎 编辑:程序博客网 时间:2024/04/29 11:38
 反射:学习反射,首先就要明白Class这个类。反射的作用也是非常有用的,在以后学习框架的时候将会特别突出。Class实例对象其实就是我们所学习和定义的java类,有人总结出这样一句话,的确很有道理,反射就是把Java类中的各种成分映射成相应的java类。一个类被类加载器加载到内存,占用一片存储空间,这个空间里面的内容就是类的字节码,而要用一个个对象来表示这一片片的空间(字节码),这些对象具有相同的类型,这个类型是Class。通过以下三种方法所得到的三个class对象是完全相同的。

              Date d1 = new Date();

              Class clazz1 = d1.getClass();

              Class clazz2 = Date.class;

              Class clazz3 = Class.forName("java.util.Date");

一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,修饰符,包等等信息也用一个个的Java类来表示。

可以使用getField来获取类的可见的成员变量,对于不可见的也就是有private修饰的必须使用getDeclaredField来获取。要获取类的方法就必须使用getMethod方法,参数包括方法的名字和方法的参数的类。所得到的Method使用invoke方法来调用。在jdk1.4和jdk1.5的invoke方法是有区别的,例如System.out.println( charAt.invoke("abcd", new Object[]{1}));,当我们将一个数组作为参数传递给invoke方法时,按jdk1.4的语法,数组中的每个元素对应一个参数,按jdk1.5的语法,整个数组是一个参数。这显然是有些矛盾的,但是经过反复的推敲可以知道,Class.getMethod方法的时候接受什么样的参数。Class.getMethod(name,Class... args)中的参数列表的args部分还是有一点困惑,它代表所要获取的那个方法的各个参数的类型的列表。

Method.invoke()接受的参数,如果一个参数为null,这意味着什么呢,这其实意味着这个方法是一个静态方法。mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});

              //mainMethod.invoke(null,(Object)new String[]{"xxx"});据说用这种方式也可以,编译器会作特殊处理,如果不加(Object),编译器会把数组转换成可变参数,加了则不转。在给main方法传递参数时,不能使用如下代码mainMethod.invoke(null,new String[]{"xxx"}),虽然这符合jdk1.5的语法要求,但是,为了兼容jdk1.4的语法,jdk把它理解成了jdk1.4的样子,所以,出现了参数类型不对的问题。

这之后张老师又给我们复习了集合的知识,在我以前看书的就对集合这一块比较陌生。collection只是一个接口,在使用的时候我们必须使用实现了该接口的集合类,比如ArrayList,hashSet等,首先要区分下这两种类型的不同。collection对象之间没有指定顺序,允许有重复的元素。Set对象之间没有指定的顺序,但是不允许有重复的元素。List指定了元素的顺序,但是允许有重复的元素。

一个类加载器能加载.class文件,那它当然也能加载classpath环境下的其他文件。可以使用Reflect.class.getClassLoader()来启用类加载器。通过使用getResourceAsStream来加载其他的文件。内省:首先介绍JavaBean,一个JavaBean就是其中的方法符合某种命名规则的一个java类,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。在Java EE开发中,经常要使用到JavaBean,JDK中提供了对JavaBean进行操作的一些API。一个JavaBean类可以不当JavaBean用,而可以当普通类用。那我会什么要把它当JavaBean用?这肯定与普通类的用法不一样!第一,别人都这么用,你就得这么用?第二,就是人家提供了一套针对javabean操作的api,用这套api比用普通类的方式更方便。一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。去掉set前缀,然后取剩余部分,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。

beanutils与PropertyUtils工具的使用:PropertyUtils.getPropety方法获得的属性值的类型为该属性本来的类型,而BeanUtils.getProperty则是将该属性的值转换成字符串后才返回。

注解:通过java.lang包,了解JDK中提供的最基本的annotation;@Deprecated,@SuppressWarnings和@Override三种注解,张老师都给我们讲解了,看的很明白,就是这些单词很陌生,看来还是要经过长期的联系才可以啊,最终达到熟能生巧。

接下来总结下如何自己来定义注解。了注解,等于打上了某种标记,没加,则等于没有某种标记,以后,其他程序可以用反射来了解你的类上面有无何种标记,看你有什么标记,就去干相应的事。标记可以加在类,方法,字段,包上,方法的参数上。定义注解就是使用public @interface 来定义的。在定义的时候,需要给定义注解的语句前面使用注解。引出@Retention注解,它的值有三种RetetionPolicy.SOURCE,RetetionPolicy.CLASS,RetetionPolicy.RUNTIME;分别是源代码级,字节码文件级,运行级。

注解@Target,Target的默认值为任何元素,用数组方式设置如下{ElementType.METHOD,ElementType.TYPE}。

 接着讲注解的属性:一个注解相当于一个贴画。如何区分呢?就可以使用注解的属性来定义,在注解定义的类里面定义方法,当我们引用的时候输入形如:@MyAnnotation(color="red")。还可以在定义注解的时候使用默认值,在方法的后面使用default关键字,后面加上默认值就可以了。里面有一个比较特殊,就是如果属性为value,如果引用的时候,只用输入一个值的时候就可以省略value=。你只有一个属性要填写,不代表你只有一个属性,因为还有默认值。同理也可以采用数组作为注解的属性,引用的时候使用形如array={1,3,5}即可,同样在只有这一个输入值的时候也可以省略array=。

原创粉丝点击