学习别人的
什么是反射?
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, 则其子类将自动具有该注解