黑马程序员——高新技术(day2)反射,JavaBean的操作和注解的应用

时间:2022-03-06 11:31:05

      ------------------ 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类型、枚举类型、注解类型、刚才这些前面类型的数组