------------------ android培训、java培训
//=====================================================================
//@TITLE:// 高新技术day2
//@AUTHOR:
// Benwolf
//=====================================================================
反射的基石--》Class类
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
八个基本数据类型:
boolean,byte,char,short
int,long,float,double,void
重点:只要是在源程序中出现的类型,都有各自的Class实例对象。
反射的概念:
反射就是把Java类中的各种成分映射成相应的Java类。表示java类的Class类先要提供一系列的方法来获取其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Filed、Method、Contructor(构造方法)、Package等等。
Constructor类:
Constructor类代表某个类中的构造方法
得到某个类所有的构造方法:
Constructor[] constructors = class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
Constructor constructor = class.forName("java.lang.String").getConstructors(StringBuffer.class);
创建实例对象:
通常方式:String str = new String(new StringBuff("abc"));
反射方式:String str = (String)constructor.newlnstance(new StringBuffer("abc"));
Class.newInstance()方法:
例子:String obj = (String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用构造方法创建实例对象。
Field类:
Field类代表某个类中的成员变量
field是字节码上的变量
RefletctPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的值不是5!
System.out.println(fieldY.get(pt1));
filed fieldX = pt1.getClass().getDeclaredField("x");//getField()私有的看不到
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
成员方法的反射:
Method类
Method类代表某个类中的一个成员方法
得到类中的某一个方法;
eg:Method CharAt = Class.forName("java.langStirng").getMethod("charAt",int class);
调用方法:System.out.println(str.char.At(1));
反射方法:System.out.println(charAt.invoke(str,1));
jdk1.4和jdk1.5的invoke方法的区别:
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[] args)
对接收数组参数的成员方法进行反射:
eg:
写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法:
普通调用方法:
TestArguments.main(new Stringp[]{"111","222","333"});
反射调用方法:
String startingClassName = args[];
Method mainMethod = class.forName(startringClassName).getMeThod("main",String[].class);
mainMethod.invoke(null,(Object)new String[]{"111","222","333"})
解决方法
mainMethod.invoke(null,new Object[]{new String{"xxx"}});
mainMethod.invoke(null,(Object)new String{"xxx"});,编译器会做处理,不把参数当做数组看待,即告诉编译器传进去的是一个对象,就不会将参数看作为若干个参数了
数组与Object的关系及其反射类型:
代码举例:
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
Object aObj1 = a1;
Object aObj2 = a4;
//Object[] aObj3 = a1;Object[] aObj4 = a3;
Object[] aObj5 = a4;
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
数组的反射:
-具有相同维数和元素类型的数组术语同一个类型,即具有相同的Class实例对象。
-代表数据的Class实例对象的getSuperClass()方法返回的父类为Object类型对应的Class。
-基本类型的一位数组可以被当做Object类型使用,不能当做Object[]类型使用,非基本类型的一维数组,既可以当做Object类型使用又可以当做Object[]类型使用。
-Arrays.aList()方法处理int[]和String[]时的差异
-Array类专门用于对数组的反射进行操作
eg:
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()){
int len = Array.getLength(obj);
for(int i=0;i<len;i++){
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
}
JavaBean:
内省-introSpector
introSpector-->JavaBean-->特殊的Java类
JavaBean的属性是根据方法的属性来定义的
类里若有get与set方法,就可以当做JavaBean来操作
Age-->如果第二个字母是小的,则把第一个字母变成小的-->age
eg:gettime-->time
getTime-->time
getCPI-->CPU
JDK中提供了对JAVABEAN进行操作的一些API,这套API称为内省。如果自己去通过getX方法访问私有的x,有一定难度。用内省这套API操作JavaBean比用普通类的方式更方便。
eclipse里快捷键出get与set方法:
Alt+Shift+s再进行选择
对JavaBean的简单内省操作:
PropertyDescriptor pd = new PropertyDescriptor(propertyName, pt1.getClass())
Method methodGetX = pd.getReadMethod();
object retval = methodGetX.invoke(pt1);
对JavaBean的复杂内省操作:
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
使用BeanUtils工具包操作JavaBean:
先只引入beanutils 包,等程序运行出错后再引入logging包
BeanUtil.setProperty(对象,"属性","值");
BeanUtil.getProperty(对象,"属性");
BeanUtil方法,在"值"的位置,以字符串对其属性进行操作。
了解和入门注解的应用:
@Deprecated——标注对应方法已经过时。
直接在刚才的类中增加一个方法,并加上@deprecated标注,在另外一个类中调用这个方法。
@Override--判断是否是重写
public boolean equals(Reflect other)方法与HashSet结合讲解。
@SuppressWarnings
如果方法体中有过时的方法,那么可以在方法上面一行加@SuppressWarnings("deprecation")
提示:在java.lang包,可以看到JDK中提供最基本的annotation。
注解的定义和反射调用
注解的应用结构:
注解的生命周期啊的三个阶段:
java源文件-->class文件-->内存中的字节码。
RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;
分别对应其字节码。
数组类型的属性:int [] arrayAttr() default{1,2,3};
@MyAnnotation(arrayAttr={2,3,4});
如果数组属性中有一个元素,这时候属性值部分可以省略大括号。
枚举类型的属性:
EnumTest TrafficLamp lamp();
@MyAnnotation(lame=EnumTest.TrafficLame.GREEN);
注释可以返回:8个基本类型、Class类型、枚举类型、注解类型、刚才这些前面类型的数组