您的位置:首页 > 职场人生

黑马程序员——内省和注解

2013-07-10 11:15 267 查看
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
一、内省:Introspection,主要操作JavaBean。

JavaBean:特定的java类,该类的方法有特定的功能,每个成员变量都有其对应的get、set方法,来操作该类中的成员。下面就是一个简单的符合JavaBean的类:

package itcast;

public class Person{
private int age;
private String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

下面是一种用内省操作Person类的例子:用到PropertyDescriptor ,描述 Java Bean 通过一对存储器方法导出的一个属性。

package itcast;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class JavaBeanDemo  {
public static void main(String[] args) throws Exception {
Person p = new Person(45, "xiaoqiang");
String propertyName = "name";
String str = "zhangsan";
Object renVal = getProperty(p, propertyName);
System.out.println(renVal);
setProperty(p,propertyName,str);
renVal = getProperty(p, propertyName);
System.out.println(renVal);
}

private static void setProperty(Object p, String propertyName, String str)
throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//用PropertyDescriptor来操作符合javabean规则的一个Person对象
PropertyDescriptor pd = new PropertyDescriptor(propertyName, p.getClass());
//获取Person类对应成员变量的set方法
Method methodSetName = pd.getWriteMethod();
methodSetName.invoke(p, str);
}

public static Object getProperty(Object p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName, p.getClass());
//获取Person类对应成员变量的get方法
Method methodGetName = pd.getReadMethod();
Object renVal = methodGetName.invoke(p);
return renVal;
}
}

另外一种内省操作:才用遍历BeanInfo的所有属性方式来查找和设置某个Person对象的name属性,通过调用Introspector类的getBeanInfo()方法来获取BeanInfo对象。

package itcast;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class JavaBeanDemo  {
public static void main(String[] args) throws Exception {
Person p = new Person(45, "xiaoqiang");
String propertyName = "name";
String str = "zhangsan";
Object renVal = getProperty(p, propertyName);
System.out.println(renVal);
setProperty(p,propertyName,str);
renVal = getProperty(p, propertyName);
System.out.println(renVal);
}

private static void setProperty(Object p, String propertyName, String str)
throws IntrospectionException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException{
BeanInfo beanInfo = Introspector.getBeanInfo(p.getClass());
PropertyDescriptor[]  pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
if(pd.getName().equals(propertyName)){
Method methodSetName = pd.getWriteMethod();
methodSetName.invoke(p,str);
break;
}
}
}

public static Object getProperty(Object p, String propertyName)
throws IntrospectionException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException{
BeanInfo beanInfo = Introspector.getBeanInfo(p.getClass());
PropertyDescriptor[]  pds = beanInfo.getPropertyDescriptors();
Object renVal = null;
for(PropertyDescriptor pd:pds){
if(pd.getName().equals(propertyName)){
Method methodGetName = pd.getReadMethod();
renVal = methodGetName.invoke(p);
break;
}
}
return renVal;
}
}

可以看出,这种操作还是比较麻烦的,由于内省使用还是比较频繁的,这样apache公司自己定义了一些方便的内省工具,如BeanUtils类;这样上面的例子可以简化为:

package itcast;

import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.BeanUtils;

public class BeanUtilsDemo {
public static void main(String[] args)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
Person p = new Person(15, "xiaoxiang");
System.out.println(BeanUtils.getProperty(p,"age"));
BeanUtils.setProperty(p, "age", 99);
System.out.println(BeanUtils.getProperty(p,"age"));
}
}

这样,使用起来就方便多了,但是在使用这些工具之前,要先将对应的jar包导入到工程中。BeanUtils支持内省操作的级联,即A类里有一个b成员变量,b有事B类的一个对象,B中又有一个才成员变量,可以使用BeanUtils.getProperty(a,"b.c")来直接获取对应的值,这个如果用基本的内省反射操作是相当麻烦的。

二、注解:

1,预定义注解:@SuppressWarnings(str):取消警告,str为何种警告,如过时警告为deprecation。保留到SOURCE阶段

                           @Deprecated:声明方法或变量已经过时。保留到RUNTIME阶段

                           @Override:声明该方法是覆盖父类的方法。保留到SOURCEC阶段

2,自定义注解:1),注解的定义:

package itcast;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//注解的注解,元注解。说明该注解保留到RUNTIME阶段
@Retention(RetentionPolicy.RUNTIME)
//说明注解作用在那些类型上
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
String color() default "blue";
String value();
int[] intChar()default{1,3,5};
}

通过在注解接口中定义抽象方法可以给注解添加属性,如果只有value属性需要指定,那么在新建注解对象时可以省略“vale=”。

2),自定义注解的应用:

package itcast;

@MyAnnotation("good")
public class AnnotationTest {
public static void main(String[] args) {
MyAnnotation annotation=null;
//isAnnotationPresent用于判断指定类型注解是否存在于该元素上
if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
annotation =(MyAnnotation) AnnotationTest.class.getAnnotation(MyAnnotation.class);
}
System.out.println(annotation.color());
System.out.println(annotation.value());
System.out.println(annotation.intChar().length);
}
}

注解属性返回值类型:基本数据类型,String,Class类型,枚举,注解以及他们的数组。如果出现其他类型,编译器会报错。

 注解Annotation功能是建立在反射机制之上的,可以对程序进行注释操作。

----------------------   ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内省 注解