Java 注解/反射

什么是注解?
在这里插入图片描述

内置注解

在这里插入图片描述

元注解

在这里插入图片描述

// 定义一个注解
// 定义一个注解
@Target(value = { ElementType.METHOD, ElementType.TYPE }) // 使用范围
@Retention(value = RetentionPolicy.RUNTIME) // 生效范围
@Documented // 表示是否将我们的注解生成在JAVADOC中
@Inherited // 子类可以继承父类的注解
public @interface MyAnnotaion {
	// 注解的参数: 参数类型 + 参数名 +() default 默认值 使用注解时,如果不传就为默认值
	String value() default "";

	// int id() default 0;

	// String[] sole() default {};
}

在这里插入图片描述

ElementType 范围:

@Target(value = { ElementType.METHOD, ElementType.TYPE }) // 多个一起使用时
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE

反射

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

类加载机制

什么时候会发生类初始化
在这里插入图片描述

获得类的信息

public static void main(String[] args)
			throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
		Class<?> c1 = Class.forName("com.java.reflection.Student");

		// 获得类的名字
		System.out.println(c1.getName()); // com.java.reflection.Student
		System.out.println(c1.getSimpleName()); // Student

		// 获得类的属性
		System.out.println("======================================================");
		Field[] fields = c1.getFields(); // 只能获取被public 修饰的属性
		System.out.println(Arrays.toString(fields)); // []

		Field[] declaredFields = c1.getDeclaredFields(); // 获取全部属性
		System.out.println(Arrays.toString(declaredFields)); // [private java.lang.String
																// com.java.reflection.Student.name,
																// private int com.java.reflection.Student.id....
		// Field field = c1.getField("id"); // 获取指定属性 只限于public
		// System.out.println(field);

		Field declaredField = c1.getDeclaredField("id"); // 获取指定属性
		System.out.println(declaredField);

		// 获得类的方法
		System.out.println("======================================================");
		Method[] methods = c1.getMethods(); // 获得本类以及父类的所有public 方法
		for (Method m : methods) {
			System.out.println(m);
		}

		Method[] declaredMethods = c1.getDeclaredMethods(); // 获取本来全部

		// 获得指定方法
		Method method = c1.getMethod("getName", null);
		Method method2 = c1.getMethod("setName", String.class); // (方法名字,参数类型)
		System.out.println(method);
		System.out.println(method2);

		// 获得指定构造器
		Constructor<?>[] constructors = c1.getConstructors();
		Constructor<?>[] declaredConstructors = c1.getDeclaredConstructors();
		Constructor<?> constructor = c1.getConstructor(String.class, int.class, int.class);
		System.out.println(constructor);

	}

有了Class对象 能做什么?

在这里插入图片描述

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

		// 获得Class 对象
		Class<?> c1 = Class.forName("com.java.reflection.Student");

		// 构造一个对象
		Student newInstance = (Student) c1.newInstance(); // 本质是调用了类的无参构造器

		// 通过有参构造器创建对象
		Constructor<?> constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
		Student newInstance2 = (Student) constructor.newInstance("小红", 15, 15);
		System.out.println(newInstance2);

		// 通过反射调用普通方法一
		Student student = (Student) c1.newInstance();
		Method setName = c1.getDeclaredMethod("setName", String.class);
		setName.invoke(student, "Lang"); // invoke 执行 (执行对象,参数);
		System.out.println(student);

		// 通过反射调用普通方法二
		Student stu = (Student) c1.newInstance();
		Method print = c1.getDeclaredMethod("print", int.class, int.class); // (方法名称,参数) 参数为空就传入null
		print.setAccessible(true); // 不能直接操作私有方法,我们需要关闭程序的安全检测 。默认false
		int invokeResult = (int) print.invoke(stu, 1, 2); // 方法 有返回值时就正常返回 无返回值则返回null
		System.out.println(invokeResult);
		System.out.println("================================");

		// 通过反射操作属性
		System.out.println("============");
		Student student2 = (Student) c1.newInstance();
		Field name = c1.getDeclaredField("name");
		name.setAccessible(true); // 不能直接操作私有属性,我们需要关闭程序的安全检测 。默认false
		name.set(student2, "Lang");
		System.out.println(student2);
	}

在这里插入图片描述

性能对比分析

	public static void test1() {
		User user = new User();
		long begin = System.currentTimeMillis();

		for (int i = 0; i < 1000000000; i++) {
			user.getAge();
		}
		long end = System.currentTimeMillis();
		System.out.println("普通方式 用时 :" + (end - begin) + "ms");
	}

	public static void test2() throws Exception {

		Class<?> c1 = Class.forName("com.java.reflection.User");
		User user = (User) c1.newInstance();
		Method method = c1.getDeclaredMethod("getAge", null);
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 1000000000; i++) {
			method.invoke(user, null);
		}
		long end = System.currentTimeMillis();
		System.out.println("反射方式 用时 :" + (end - begin) + "ms");
	}

	public static void test3() throws Exception {
		Class<?> c1 = Class.forName("com.java.reflection.User");
		User user = (User) c1.newInstance();
		Method method = c1.getDeclaredMethod("getAge", null);
		method.setAccessible(true); // 关闭安全检查
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 1000000000; i++) {
			method.invoke(user, null);
		}
		long end = System.currentTimeMillis();
		System.out.println("关闭安全检查反射方式 用时 :" + (end - begin) + "ms");
	}

在这里插入图片描述

反射操作泛型

在这里插入图片描述

// 通过反射获取泛型
public class Test5 {
	public void test01(Map<String, User> map, List<User> list) {
		System.out.println("test01");
	}

	public Map<String, User> test02() {
		System.out.println("test02");
		return null;
	}

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

		// 获取参数泛型类型
		Method method = Test5.class.getMethod("test01", Map.class, List.class);
		Type[] genericParameterTypes = method.getGenericParameterTypes(); // 获取参数泛型类型
		for (Type g : genericParameterTypes) {
			System.out.println(g); // java.util.Map<java.lang.String, com.java.reflection.User>
									// java.util.List<com.java.reflection.User>
			if (g instanceof ParameterizedType) {
				Type[] actualTypeArguments = ((ParameterizedType) g).getActualTypeArguments();

				for (Type a : actualTypeArguments) {
					System.out.println(a);
				}
			}

		}
		System.out.println("---");

		// 获取方法返回值泛型类型
		Method method1 = Test5.class.getMethod("test02", null);
		Type returnType = method1.getGenericReturnType(); // 获取返回值泛型类型
		if (returnType instanceof ParameterizedType) {
			Type[] actualTypeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
			for (Type a : actualTypeArguments) {
				System.out.println(a);
			}
		}

	}
}

反射获取注解信息

案例:

实体类:

@TableLang("table_Teacher")
class Teacher {
	@FieldLang(columnName = "t_name", type = "varchar", length = 25)
	private String name;
	@FieldLang(columnName = "t_age", type = "int", length = 3)
	private Integer age;
	@FieldLang(columnName = "t_id", type = "int", length = 15)
	private Long id;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Long getId() {
		return id;
	}

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

}

自定义注解:

// 自定义注解-类注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableLang {
	String value();
}

// 自定义注解-字段注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldLang {
	String columnName();

	String type();

	int length();
}
	public static void main(String[] args) throws Exception {
		Class<?> c1 = Class.forName("com.java.reflection.Teacher");

		// 获得注解
		Annotation[] annotations = c1.getAnnotations();
		for (Annotation a : annotations) {
			System.out.println(a);
		}

		// 获得注解的值
		TableLang annotation = c1.getAnnotation(TableLang.class);
		String value = annotation.value();
		System.out.println(value);

		// 获得类指定注解
		Field field = c1.getDeclaredField("name");
		FieldLang fieldLang = field.getAnnotation(FieldLang.class);
		System.out.println(fieldLang.columnName());
		System.out.println(fieldLang.type());
		System.out.println(fieldLang.length());

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值