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

---------------------- 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

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值