Java注解与反射

我的网站:欢迎访问嗷

注解

概念

也叫元数据,标签

注解和注释

注释:是写给程序员看的 帮助开发人员理解代码

注解:给java程序看的,帮助程序理解代码 也叫标签

学习注解的好处

1.使代码简洁、清爽

2.以后使用别人的注解(公司自己开发的框架 开源框架(Spring SpringMvc SpringBoot))

3.装逼… 一个注解完成一系列功能

4.分析别人代码

注解作用

1.生成文档

2.分析代码

3.校验

4.自定义注解可以根据情况添加功能

注解的使用(三要素)

1.拿到注解 (定义注解)

2.在适当位置使用 (作用范围)

3.完成某项功能

JDK四大内置注解

@Override 校验是否方法覆写

@deprecated 标记方法过时 过时的方法依然可以使用,但不建议

@SupperssWarings 抑制警告

@SafeVarargs 抑制堆污染警告 有了这个注解jvm就不会再去校验 比如定义泛型时传入类型不一致

元注解

是注解里面的注解,约束注解的范围,生命周期,生成文档,能够被子类方法

@Target 用来约束注解作用范围(类 方法 构造方法 字段)

@Retention 约束注解的生命周期(Java源文件 字节码文件 运行时)

@Documented 自定义注解的时候,使用此元注解,就会把自定义的注解一并生成到API中

@Inherited 自定义的注解使用了此元注解修饰,在类上使用自定义注解的时候 从这个类的子类上也能获取该注解的信息

自定义注解

1.作用范围

2.完成功能

语法

@Inherited 子类可以获得父类上面的注解信息

@Documented 生成API文档

@Retention 声明生命周期

@Target 指定作用范围 默认不指定范围的时候是全局都可以使用

public @interface 注解名{

}

反射

基本概念

通过字节码文件去获取到类中的信息(无论私有还是公有)

程序运行的时候动态地区获取到类中的相关信息

类中的信息:字段 方法 构造方法 注解

全限定名:包名.类名

优点:功能强大 灵活

缺点:破坏封装 效率较低

获取对象字节码文件

类:

1.类名.class 2.对象名.getClass() 3.Class.forName(全限定名:包名+类名)
接口:

1.接口名.class 2.Class.forName(全限定名:包名+类名)
数组:

1.对象名.getClass() 2.数组类型.class
基本数据类型

1.基本数据类型.class 2.对应包装类型.Type
Void:

类名.class

Demo

package com.ifueen.classtest.reflect;

import static org.junit.Assert.*;

import java.util.Date;

import org.junit.Test;

/**
 * @author admin
 *获取字节码文件
 */
public class ByteCode {
	
	@Test
	public void test() throws Exception {
		
		ByteCode byteCode = new ByteCode();
		//通过类名.class获取
		Class<ByteCode> b1 = ByteCode.class;
		System.out.println(b1);
		//通过对象名.getclass
		Class<? extends ByteCode> class1 = byteCode.getClass();
		System.out.println(class1);
		//通过全限定名来获取
		Class forName = Class.forName("com.ifueen.classtest.reflect.ByteCode");
		System.out.println(forName);
		//接口获取一:通过接口名.class获取
		Class<MyInterface> m1 = MyInterface.class;
		System.out.println(m1);
		//通过全限定名获取接口的字节码文件
		Class forName2 = Class.forName("com.ifueen.classtest.reflect.MyInterface");
		System.out.println(forName2);
		//数组获取一:通过对象名.getClass获取
		int [] arr = new int[5];
		Class<? extends int[]> class2 = arr.getClass();
		System.out.println(class2);
		//数组获取二:通过数组[].class获取
		Class class3 = int[].class;
		System.out.println(class3);
		//基本数据类型获取一:通过类名.class
		String name = "山泥若";
		Class<String> class4 = String.class;
		System.out.println(class4);
	}

}

通过反射获取对象

如果是获取共有的不用设置访问权限 如果是私有的则需要设置访问权限
获取构造方法:
公共无参的: 字节码对象.newInstance 公共有参的: 字节码对象.getConstructor(参数的字节码);
获取方法: 字节码对象.getMethod(方法名称,参数字节码); 执行: 方法对象.invoke(对象,实际参数);
获取字段: 字节码对象.getFiled(字段名称); 设置值 :字段对象.set(对象,实际参数);
获取注解 : 字节码对象.getAnnotation(注解的字节码); 注解对象.对应的方法 获取值

Demo

自定义注解:MyAnnotation

package com.ifueen.classtest.reflect;

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

@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {
	String star();
}

JavaBean类:MyTest

package com.ifueen.classtest.reflect;

@MyAnnotation(star="我们分手吧")
public class MyTest {
	public String name;
	public Integer age;
	private String str;
	public MyTest() {
		// TODO Auto-generated constructor stub
	}
	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;
	}
	private MyTest(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "MyTest [name=" + name + ", age=" + age + "]";
	}
	public MyTest(String name) {
		super();
		this.name = name;
	}
	public void eat(){
		System.out.println("我要吃汉堡");
	}
	private void show(String name){
		System.out.println("这是一个结婚的车队"+name);
	}
	public String getStr() {
		return str;
	}
	public void setStr(String str) {
		this.str = str;
	}
	
}

测试类:

package com.ifueen.classtest.reflect;

import static org.junit.Assert.*;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;import java.util.Set;

import org.junit.Test;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class ReflectTest {

	/**
	 * 测试反射
	 * @throws Exception 
	 */
	@Test
	public void test() throws Exception {
		//拿到字节码文件
		Class<MyTest> forName = (Class<MyTest>) Class.forName("com.ifueen.classtest.reflect.MyTest");
		//调用无参构造方法
		/*MyTest m1 = forName.newInstance();
		m1.setName("人民不需要自由");
		m1.setAge(34);
		System.out.println(m1);*/
		
		//调用有参构造方法
		/*Constructor<MyTest> c1 = forName.getConstructor(String.class);
		MyTest m2 = c1.newInstance("给我吃一口好不好");
		System.out.println(m2);*/
		
		//调用私有化的构造方法
		/*Constructor<MyTest> c2 = forName.getDeclaredConstructor(String.class,Integer.class);
		//设置权限
		c2.setAccessible(true);
		MyTest m2 = c2.newInstance("你在干什么啊",65);
		System.out.println(m2);*/
		
	}
	
	/**
	 * 通过反射获取方法
	 * @throws Exception 
	 */
	@Test
	public void testmethod() throws Exception{

		//通过反射调用公有方法
		Class<MyTest> forName = (Class<MyTest>) Class.forName("com.ifueen.classtest.reflect.MyTest");
		/*Method method = forName.getMethod("eat");
		MyTest m1 = forName.newInstance();
		//调用方法
		method.invoke(m1);*/
		//私有方法
		/*Method method = forName.getDeclaredMethod("show", String.class);
		//设置权限
		method.setAccessible(true);
		MyTest m2 = forName.newInstance();
		method.invoke(m2, "王小波");*/
		
		
	}
	
	/**
	 * 通过反射获取字段
	 * @throws Exception 
	 */
	@Test
	public void testfield() throws Exception {
		Class<MyTest> forName = (Class<MyTest>) Class.forName("com.ifueen.classtest.reflect.MyTest");
		//获取公有字段,参数为字段名
		/*Field f1 = forName.getField("name");
		String name = "太宰治";
		//通过反射获取新的对象
		MyTest myTest = forName.newInstance();
		f1.set(myTest, name);
		System.out.println(myTest.name);*/
		//获取私有字段
		/*Field f2 = forName.getDeclaredField("str");
		//设置权限
		f2.setAccessible(true);
		MyTest myTest = new MyTest();
		f2.set(myTest, new String("吃薯条"));
		System.out.println(myTest.getStr());*/
	}
	
	/**
	 * 获取注解
	 * @throws Exception 
	 */
	@Test
	public void testAnnotation() throws Exception {
		Class<MyTest> forName = (Class<MyTest>) Class.forName("com.ifueen.classtest.reflect.MyTest");
		//拿到注解
		MyAnnotation a1 = forName.getAnnotation(MyAnnotation.class);
		System.out.println(a1);
		//拿到注解里面的方法
		String star = a1.star();
		System.out.println(star);
		//测试注解是否被继承
		/*Class<Separate> s1 = Separate.class;
		MyAnnotation a2 = s1.getAnnotation(MyAnnotation.class);
		String star = a2.star();
		System.out.println(star);*/
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值