注解与反射(4)--反射操作注解

动态创建对象执行方法

  • 创建类的对象:调用Class对象的newInstance()方法
    • 类必须有一个无参构造器
    • 类的构造器的访问权限需要足够
  • 没有无参构造器时需要在操作的时候明确调用类中的构造器,并将参数传递进去之后,才可以实例化操作。步骤:
    • 通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器
    • 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数
    • 通过Constructor实例化对象
  • 调用指定方法:通过反射,调用类中的方法,通过Method类完成
    • 通过Class类的getMethod(String name,Class … parameterType)方法取得一个Method对象,并设置此方法操作时所需的参数类型
    • 之后使用Object invoke(Object obj, Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息
      • Object对应原方法的返回值,若原方法无返回值,此时返回null
      • 若原方法为静态方法,此时形参Object obj可为null
      • 若原方法形参列表为空,则Object[] args为null
      • 若原方法声明为private,则需要在调用此方法invoke()方法前,显示调用方法对象的setAccessible(ture)方法,将可访问private的方法
  • setAccessible()方法:
    • Method和Field、Constructor对象都有setAccessible()方法
    • setAccessible作用时启动和禁用访问安全检查的开关
    • 参数值为true则指示反射的对象在使用时应该取消java语言访问检查
      • 默认为false
      • 提高反射的效率,如果代码中必须用反射,而该语句代码需要频繁的被调用,那么请设置为true
      • 使得原本无法访问的私有成员也可以访问
    • 参数值为false则指示反射的对象应该实施java语言访问检查
package Annotation;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/* 动态的创建对象,通过反射 */
public class Test9 {

	@SuppressWarnings({ "unchecked", "rawtypes", "deprecation" })
	public static void main(String[] args) throws 
	ClassNotFoundException, InstantiationException, 
	IllegalAccessException, NoSuchMethodException, 
	SecurityException, IllegalArgumentException, 
	InvocationTargetException, NoSuchFieldException {
		
		/* 获得class对象 */
		Class c1 = Class.forName("Annotation.User");
		
		/* 构造一个对象 */
		/* 本质上是调用了无参构造器 */
		User user = (User)c1.newInstance();
		System.out.println(user);
		
		/* 通过构造器创建对象 */
		Constructor constructor =  c1.getDeclaredConstructor(String.class,
				int.class,int.class);
		User user2 = (User)constructor.newInstance("name",1,2);
		
		System.out.println(user2);
		
		/* 通过反射调用普通方法 */
		User user3 = (User)c1.newInstance();
		/* 通过反射获得一个方法 */
		Method setName = c1.getDeclaredMethod("setName", String.class);
		/* invoke:激活 第一个参数为对象,第二个参数为方法的值 */
		setName.invoke(user3, " 1 ");
		System.out.println(user3.getName());
		
		/* 通过反射操作属性 */
		User user4 = (User)c1.newInstance();
		Field name = c1.getDeclaredField("name");
		
		/* 不能直接操作私有属性,需要关闭程序的安全监测
		 * 属性或方法的setAccessible(true) */
		name.setAccessible(true);
		name.set(user4, " 2 ");
		System.out.println(user4.getName());
	}
	
}

性能对比分析

package Annotation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/* 分析性能问题 */
public class Test10 {

	/* 1.普通方式调用 */
	public static void test01() {
		
		User user = new User();
		
		long startTime = System.currentTimeMillis();
		
		for(int i = 0; i < 1000000; i++) {
			user.getName();
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("普通方式执行:"+ 
		(endTime - startTime) + "ms");
	}
	
	/* 3.反射方式调用 */
	public static void test02() throws NoSuchMethodException, 
	SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		User user = new User();
		Class c1 = user.getClass();
		
		Method getName = c1.getDeclaredMethod("getName", null);
		
		
		long startTime = System.currentTimeMillis();
		
		for(int i = 0; i < 1000000; i++) {
			getName.invoke(user, null);
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("反射方式执行:"+ 
		(endTime - startTime) + "ms");
	}
	
	/* 3.反射方式调用,关闭检测 */
	public static void test03() throws NoSuchMethodException, 
	SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		User user = new User();
		Class c1 = user.getClass();
		
		Method getName = c1.getDeclaredMethod("getName", null);
		getName.setAccessible(true);
		
		long startTime = System.currentTimeMillis();
		
		for(int i = 0; i < 1000000; i++) {
			getName.invoke(user, null);
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("关闭检测执行:"+ 
		(endTime - startTime) + "ms");
	}
	
	public static void main(String[] args) throws NoSuchMethodException, 
	SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		test01();
		test02();
		test03();
	}
}

输出:
普通方式执行:3ms
反射方式执行:22ms
关闭检测执行:8ms
  • 结论:如果反射调用很多的情况下,关闭检测可以大大提高效率

获取泛型

  • ParameterizedType:表示一种参数化类型,比如Collection
  • GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
  • TypeVariable:是各种类型变量的公共父接口
  • WildcardType:代表一种通配符类型表达式
package Annotation;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test11 {

	public void test01(Map<String,User> map, List<User> list) {
		System.out.print("test01");
	}
	
	public Map<String,User> test02(){
		System.out.print("test02");
		return null;
	}
	
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		Method method = Test11.class.getMethod("test01", Map.class, List.class);
		
		Type[] gs = method.getGenericParameterTypes();
		for(Type g : gs) {
			System.out.println(g);
			
			if(g instanceof ParameterizedType) {
				Type[] actuals = ((ParameterizedType) g).getActualTypeArguments();
				for(Type actual : actuals) {
					System.out.println(actual);
				}
			}
		}
		
		method = Test11.class.getMethod("test02", null);
		Type ge = method.getGenericReturnType();
		
		if(ge instanceof ParameterizedType) {
			Type[] actuals = ((ParameterizedType) ge).getActualTypeArguments();
			for(Type actual : actuals) {
				System.out.println(actual);
			}
		}
		
	}
}

反射操作注解

  • ORM:
    • Object relationship Mapping–对象关系映射
    • 类和表结构对应
    • 属性和字段对应
    • 对象和记录对应
package Annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

/* 反射操作注解 */
public class Test12 {
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void main(String[] args) throws ClassNotFoundException, 
	NoSuchFieldException, SecurityException {
		Class c1 = Class.forName("Annotation.Student2");
		
		/* 通过反射获得注解 */
		Annotation[] annotations = c1.getAnnotations();
		for(Annotation annotation : annotations) {
			System.out.println(annotation);
		}
		
		/* 获取注解的value值 */
		Table table = (Table)c1.getAnnotation(Table.class);
		String value = table.value();
		System.out.println(value);
		
		/* 获得类指定的注解 */
		Field f = c1.getDeclaredField("name");
		Fieldd a = f.getAnnotation(Fieldd.class);
		System.out.println(a.columnName());
		System.out.println(a.type());
		System.out.println(a.length());
	}

}

@Table("database")
class Student2{
	
	@Fieldd(columnName = "db_id", type = "int", length = 10)
	private int id;
	@Fieldd(columnName = "db_age", type = "int", length = 10)
	private int age;
	@Fieldd(columnName = "db_name", type = "varchar", length = 10)
	private String name;
	
	public Student2() {
		
	}
	
	public Student2(int id, int age, String name) {
		this.setAge(age);
		this.setId(id);
		this.setName(name);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	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;
	}
	
	@Override
	public String toString() {
		return "Student2{" + 
				"id=" + id + 
				", age=" + age + 
				", name=" + name + '\'' + 
				'}';
	}
}

/* 类名的注解 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
	String value();
}

/* 属性的注解 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldd{
	String columnName();
	String type();
	int length();
	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值