我的网站:欢迎访问嗷
注解
概念
也叫元数据,标签
注解和注释
注释:是写给程序员看的 帮助开发人员理解代码
注解:给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);*/
}
}