自定义注解:
案例:
package cn.tedu.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//这个类用来测试自定义注解
public class Test1_Annotation {
public static void main(String[] args) {
}
}
//第一步:自定义注解,注意语法和java不同 !!
//1,定义注解需要用:@interface来标志 注解名
//2,@Target指定注解可以存在的位置
//@Target(ElementType.METHOD)//3,注解可以出现在方法上
@Target({ ElementType.METHOD , ElementType.TYPE })//7,注解还可以出现在多个位置上
//4,@Retention指定注解可以存在的生命周期
@Retention(RetentionPolicy.SOURCE)//5,注解可以存源在文件中
@interface Test{//定义了一个注解,名字叫Test
//8,定义注解的功能--给注解添加属性
// int age();//这个可不是age方法,而是注解中定义的age属性的语法
int age() default 0 ;//10,为了使用时方便,age属性设置默认值
//12,特殊属性value
String value() ;
// String value() default "jack";//14,属性有了默认值就不再找你要了
}
//第二步:使用注解
//6,使用注解时,只要在指定的注解名字前面加上@即可使用
class Hello{
String name;
// @Test 注解没有属性时,可以直接使用,有属性了就必须给属性赋值
//9,定义了普通的age属性,并赋值,写法age=10,如果用时太麻烦不想赋值
// @Test(age=10)
//11,由于age属性有了默认值,所以直接用就可以了
@Test("add")//13,给value属性赋值可以简写"add",就相当于value="add"
public void add() {
System.out.println("add()");
}
}
反射:
三种得到字节码对象办法:
Class.forName(“类的全路径”);
类名.class
对象.getClass();
常用方法:
获得包名、类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名
!!成员变量定义信息
getFields()//获得所有公开的成员变量,包括继承的变量
getDeclaredFields()//获得本类定义的成员变量,包括私有,不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
!!构造方法定义信息
getConstructor(参数类型列表)//获得公开的构造方法
getConstructors()//获得所有公开的构造方法
getDeclaredConstructors()//获得所有构造方法,包括私有
getDeclaredConstructor(int.class, String.class)
方法定义信息
getMethods()//获得所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获得本类定义的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名, int.class, String.class)
反射新建实例
c.newInstance();//执行无参构造
c.newInstance(6, "abc");//执行有参构造
c.getConstructor(int.class, String.class); //执行含参构造,获取构造方法
反射调用成员变量
c.getDeclaredField(变量名); //获取变量
c.setAccessible(true); //使私有成员允许访问
f.set(实例, 值); //为指定实例的变量赋值,静态变量,第一参数给 null
f.get(实例); //访问指定实例的变量的值,静态变量,第一参数给 null
反射调用成员方法
获取方法
Method m = c.getDeclaredMethod(方法名, 参数类型列表);
m.setAccessible(true) ;//使私有方法允许被调用
m.invoke(实例, 参数数据) ;//让指定的实例来执行该方法
暴力反射案例:
//这个类用来测试暴力反射
public class Test2_Reflect2 {
@Test
public void getFiledd() throws Exception {
//1,获取Class对象
Class<?> clazz = Person.class;
//2,获取私有属性
Field field = clazz.getDeclaredField("name");
//3,获取属性的数据类型
System.out.println(field.getType().getName());
//4,设置私有属性的值
//set(m,n)-m是你要给哪个对象设置值,n是要设置的具体值
Object obj = clazz.newInstance();
// !! 暴力手段设置---私有可见
field.setAccessible(true);
field.set(obj, "rose");
//5,获取私有属性的值
System.out.println(field.get(obj));
}
@Test
public void getFunctions() throws Exception{
//1,获取Class对象
Class<?> clazz = Person.class;
//2,暴力反射 私有方法
//getDeclaredMethod(m,n,o,p.....)-m是要执行的方法名-n o p是方法需要的参数类型
Method method = clazz.getDeclaredMethod("save", int.class,String.class);
//3,暴力反射 执行私有方法
//invoke(m,n,o,p....)-m是要执行哪个对象的方法-n o p是方法需要传递的参数
Object obj = clazz.newInstance();
//设置私有可见
method.setAccessible(true);
//执行方法
method.invoke(obj, 10,"xiongda");
}
}