学习别人的
什么是反射?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射帮我们从类中解剖出构造函数、方法和成员变量(属性)。然后把解剖出来的部分,分别用Constructor、Method、Field对象表示。
反射构造方法
public class Person{
public Person(){
System.out.println("默认无参构造方法");
}
public Person(String name){
System.out.println("姓名"+name);
}
public Person(String name,int age){
System.out.println(name+"="+age);
}
private Person(int age){
System.out.println("年龄"+age);
}
}
public class Demo{
//反射无参的构造函数//反射一个参数的构造函数,反射多个参数的构造函数相似
@Test
public void test1() throws Exception{
Class clazz = Class.forName("com.cj.test.Person");//Person类在内存中的字节码对象
Constructor c = clazz.getConstructor(null);//得到Person类的构造方法,可以创建对象
c.newInstance(null);
}
反射私有的构造函数 private Person(int age)
@Test
public void test2() throws Exception{
Class clazz = Class.forName("com.cj.test.Person");//Person类在内存中的字节码对象
Constructor c = clazz.getDeclaredConstructor(null);//得到Person类的私有构造方法
c.setAccessible(true);//暴力反射
c.newInstance(20);
}
java得到类的字节码的三种方式,即获取反射的三种方法:
1.通过new对象实现反射机制 对象.getClass();
2.通过路径实现反射机制 Class.forName("com.cj.test.Person");
3.通过类名实现反射机制 类名.class;
public class Get {
//获取反射机制三种方式
public static void main(String[] args) throws ClassNotFoundException {
//方式一(通过建立对象)
Student stu = new Student();
Class classobj1 = stu.getClass();
System.out.println(classobj1.getName());
//方式二(所在通过路径-相对路径)
Class classobj2 = Class.forName("fanshe.Student");
System.out.println(classobj2.getName());
//方式三(通过类名)
Class classobj3 = Student.class;
System.out.println(classobj3.getName());
}
}
注解
在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。
1、Junit会在运行时检查方法上是否存在此注解,如果存在,就通过 反射 来运行你的方法。
2、注解是代码里的特殊标记,它可以用于替代配置文件,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行
自定义注解
1、定义注解本身
使用关键字@interface定义一个类而已。这个类就是注解。
如:public @interface MyAnnotation{ }
2、定义注解中的属性
基本形式:类型 属性名称();
比如:String name();
注解属性定义完以后,使用:@MyAnnotationDemo1(name=“hello”)
特别注意:注解的属性的类型只能是:基本类型、String、Class、枚举、注解类型及以上类型的一维数组。
3、定义注解属性的默认值
类型 属性名称() default 默认值;
4、注解中的特殊属性
(1)、特殊属性value:如果注解中只有一个属性,而且这个属性的名称是value的话,那么使用注解时可以省略value=部分,可以直接写成这样@MyAnnotation(“xxx");
(2)、特殊类型[] value():如果注解中只有一个属性,而且这个属性名称是value且数据类型是数组,那么
使用方式:四种都ok,根据情况而定
@MyAnnotationDemo1(value={“a”,“b”})
@MyAnnotationDemo1({“a”,“b”})
@MyAnnotationDemo1({“a”})
@MyAnnotationDemo1(“a”)
元注解
简单的来说服务于注解的注解就是元注解,它主要用来标识你写的注解保留范围(作用范围)以及出现的位置
JDK中定义了四种元注解:
@Retention:注解的保留范围,是个枚举,有如下可选值
@Retention(RetentionPolicy.SOURCE) //注解存在于源文件中
@Retention(RetentionPolicy.CLASS) //注解存在于源字节码文件中
@Retention(RetentionPolicy.RUNTIME) //注解存在于运行时
@Target:注解出现的位置(比如字段上、方法上等),也是个枚举,有如下可选值
@Target(ElementType.TYPE)
@Target(ElementType.FIELD) //字段
@Target(ElementType.METHOD) //方法
@Target(ElementType.PARAMETER)
@Target(ElementType.CONSTRUCTOR)
@Target(ElementType.LOCAL_VARIABLE)
@Target(ElementType.ANNOTATION_TYPE)
@Target(ElementType.PACKAGE)
@Target(ElementType.TYPE_PARAMETER)
@Target(ElementType.TYPE_USE)
@Documented: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
@Inherited: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的 Annotation, 则其子类将自动具有该注解