lesson9:java的反射,注解总结

一.理解反射

反射机制是用来描述所有的类
Class 描述类本身 Field 描述属性 Method描述方法 Construtor描述类构造方法 package描述类的包 Annotion 描述类中的注解(注解可以放在方法,参数,类上面,方法上等)

二.反射的基本使用

1.基本操作:

/**
 * @author Seven 测试的实体类
 *
 */
public class Person {

	public String name;

	private int age;

	public void eat(String food) {
		System.out.println("person eat " + food);
	}

	private void eat() {
		System.out.println("person eat something!");
	}

	@MyAnnotation({"小明","12"})
	public Person() {
		System.out.println("constructor");
	}

	public Person(String constructor) {
		System.out.println("constructor:" + constructor);
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	
}


/**
 * @author Seven 测试反射当中的一些方法
 *
 */
public class TsReflect {

	public static void main(String[] args) {
		try {

			// 关于类的一些操作
			Class clz = Class.forName("com.ts.annotionandreflect.Person");
			System.out.println(clz.getModifiers()); // 获取类的修饰符
			System.out.println(clz.getName());// 获取类全名
			System.out.println(clz.getSimpleName());// 获取类名
			Package p = clz.getPackage();
			System.out.println(p.getName());// 获取类包名
			Class clzSuper = clz.getSuperclass();// 获取超类
			System.out.println(clzSuper.getName());
			Class[] clzInterface = clz.getInterfaces();// 获取类的实现接口

			Person object = (Person) clz.newInstance();// 相当于调用类的默认无参数构造方法 如果方法重写过 可能会引起异常

			// 关于属性的一些操作
			Field fieldName = clz.getField("name");// 获取公有属性,包含父类的属性
			fieldName.getModifiers();// 属性的修饰符
			fieldName.getType();// 属性的类型
			fieldName.getName();// 属性名
			fieldName.set(object, "field"); // 给属性赋值
			String name = (String) fieldName.get(object);
			System.out.println(name);
			// 所有属性
			Field fieldAge = clz.getDeclaredField("age");// 获取所有属性,只能获取本类的属性
			fieldAge.getModifiers();// 属性的修饰符
			fieldAge.getType();// 属性的类型
			fieldAge.getName();// 属性名
			fieldAge.setAccessible(true); // 表示私有属性可直接被操作
			fieldAge.set(object, 12); // 给属性赋值
			int age = (Integer) fieldAge.get(object);
			System.out.println(age);

			// 关于方法的一些操作

			Method method = clz.getMethod("eat", String.class); // 获取公有的方法 自己或父类
			method.getModifiers();// 方法的修饰符
			method.getReturnType();// 方法的发返回值类型
			method.getName();// 获取方法名
			method.getParameterTypes(); // 获取方法的参数列表类型
			method.getExceptionTypes(); // 返回方法的抛出异常类型
			method.invoke(object, "foot");

			Method method1 = clz.getDeclaredMethod("eat"); // 获取所有方法 只能是本类的方法
			method1.setAccessible(true);// 表示私有方法可直接被操作
			method1.invoke(object);

			// 构造方法

			Constructor constructor = clz.getConstructor(String.class);
			constructor.getModifiers();// 方法的修饰符
			constructor.getName();// 获取方法名
			constructor.getParameterTypes(); // 获取方法的参数列表类型
			constructor.getExceptionTypes(); // 返回方法的抛出异常类型
			Object objectCons = constructor.newInstance("construct"); // 生成对象
			Constructor constructor1 = clz.getConstructor();
			Object objectCons1 = constructor1.newInstance(); // 生成对象

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

2.利用反射提供一个生成对象的方法达到控制反转的效果:

/**
 * @author Seven 利用反射来生成无逻辑功能的实体对象,不用在去new一个对象
 *
 */
public class TsReflectPerson {

	private String name;
	
	public void setName(String name) {
		System.out.println("name:"+name);
	}
	/**
	 * @param clz  所需生成的类的类对象
	 * @return 返回clz类对应的对象 IOC控制反转 如果还要注入信息叫DI(依赖注入它的前提是有IOC)
	 */
	public static Object getBean(Class clz) {
		Object object=null;
		try {
			object= clz.newInstance();
			
			
			//做个DI 注入信息
			Field[] fields=clz.getDeclaredFields();
			for (Field field : fields) {
				String fieldName=field.getName();
				StringBuilder sb=new StringBuilder("set").append(fieldName.substring(0,1).toUpperCase()).append(fieldName.substring(1));
				Method setMethod=clz.getMethod(sb.toString(),field.getType());
				setMethod.invoke(object, "12");//可以把信息放到文件中 读取进去
			}
			
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return object;
	}
	
	public static void main(String[] args) {
		
		System.out.println(getBean(TsReflectPerson.class));
		
	}
	
}

三.理解注解

Annotation(注解)
1.可以写在类、属性、方法、构造方法、参数前面,一般是@xxx[{信息}]
2.作用:
a.注释说明作用,比如:@Deprecated 表示已过时的api;
b.用来做代码的检测和验证 比如:@override
c.可以携带信息(内容)只能携带基本数据类型 String 枚举 、注解类型、或数组类型(以上类型的数组) @SuppressWarnings(“unused”) 表示定义变量从未被使用
3.自定义注解:

@Retention(RetentionPolicy.RUNTIME)//元注解 定义注解存在的作用域 比如这里的运行时的作用域
@Target({ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.CONSTRUCTOR}) //元注解 定义注解放置的位置 比如这里能放到属性中
public @interface MyAnnotation {
//	@Inherited 也是元注解 表示注解可以被继承
//	@Documented 文档类型的元注解 表示能被文档记录
	
//注解的方法必须有返回值 返回值类型必须是基本数据类型 String 枚举 、注解类型、或数组类型(以上类型的数组)
	String[] value(); //方法没有参数 方法的作用是把信息给别人 如果只有一个方法名叫value 使用时可以省略方法名
}

四.注解的使用(反射配合使用,利用注解反射生成对象)


public class TsAnnotation {

	public static void main(String[] args) throws Exception {

		// 解析AnnotationPerson类的注解 需要用到反射技术 注解的一般使用
		// 1.获取class对象
		Class clz = Person.class;
		// 2.获取属性
		Field field = clz.getDeclaredField("name");
		// 3.获取属性上的注解对象
		Annotation myTsAnnotation = field.getAnnotation(MyAnnotation.class);
		// 4.获取注解的class对象
		Class clzAnnotation = myTsAnnotation.getClass();
		// 5.获取注解的方法
		Method method = clzAnnotation.getMethod("value");
		// 6.执行注解方法,获取传递的信息
		String[] strs = (String[]) method.invoke(myTsAnnotation);
		for (String string : strs) {
			System.out.println(string);
		}
		
		System.out.println(getBean("com.ts.annotionandreflect.AnnotationPerson"));
		
	}

	/**
	 * @param clzName 
	 * @return  通过注解反射的技术来获取对象
	 * @throws Exception
	 */
	public static  Object getBean(String clzName) throws Exception {
		Object object = null;
		Class clz=Class.forName(clzName);
//		clz.newInstance();
		Constructor con=clz.getConstructor();
		object=con.newInstance();
		//获取注解中的携带信息 给对象赋值 
		Annotation annotation=con.getAnnotation(MyAnnotation.class);
		Class annotationClass=annotation.getClass();
		Method method=annotationClass.getMethod("value");
		String[] strs=(String[]) method.invoke(annotation);


		//获取类属性的set方法
		Field[] fields = clz.getDeclaredFields();
		for (int i=0; i<fields.length; i++) {
			String fieldName=fields[i].getName();
			StringBuilder sb=new StringBuilder("set").append(fieldName.substring(0,1).toUpperCase()).append(fieldName.substring(1));
			Method setMethod=clz.getMethod(sb.toString(), fields[i].getType());
			System.out.println(setMethod.getName()+","+strs[i]);
			//转换属性类型
			setMethod.invoke(object,fields[i].getType().getConstructor(String.class).newInstance(strs[i]));
			
		}
//		
		return object;

	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值