Java反射机制:
参考博客:http://www.cnblogs.com/bojuetech/p/5896551.html
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取的信息以及状态调用对象的方法的功能成为Java语言的反射机制
Class:描述类本身的类
Class是一个类,一个描述类的类(即描述类本身),封装了 描述方法的Method,描述字段的Field,描述构造器的Contstructor等属性
对象反射可以得到的信息:某个类的数据成员名、方法和构造器、类实现的接口
对于每个类而言,JRE都为其保留一个不变的Class类型的对象,一个Class对象包含了特定某个类的有关信息
Class对象只能由系统建立对象
一个类在JVM中只会有一个Class实例
反射机制获取类有三种方法:
直接通过类名.class
clazz = Person.class;  
通过对象的getClass()方法获取
Object obj = new Person(); clazz = obj.getClass();
通过全类名获取,但可能抛出ClassNotFoundException异常
clazz = Class.forName("com.java.reflection.Person");  
clazz使用newInstance创建对象:
使用Class类的newInstance()创建类的一个对象
实际调用的是类的无参构造器(所以写类的时候,要写一个无参的构造器)
Class clazz = Class.forName("com.java.reflection.Person");  
  
Object obj = clazz.newInstance();  
ClassLoader加载器:
类加载器是用于将类装入JVM的
JVM有两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)
JVM运行时会产生3个类加载器组成的初始化加载器层次结构:

public void testClassLoader1() throws ClassNotFoundException, IOException { //1、获取一个系统的类加载器 ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println("系统的类加载器-->" + classLoader); //2、获取系统类加载器的父类加载器(扩展类加载器(extensions classLoader)) classLoader = classLoader.getParent(); System.out.println("扩展类加载器-->" + classLoader); //3、获取扩展类加载器的父类加载器 //输出为Null,无法被Java程序直接引用 classLoader = classLoader.getParent(); System.out.println("启动类加载器-->" + classLoader); //4、测试当前类由哪个类加载器进行加载 ,结果就是系统的类加载器 classLoader = Class.forName("com.java.reflection.Person").getClassLoader(); System.out.println("当前类由哪个类加载器进行加载-->"+classLoader); //5、测试JDK提供的Object类由哪个类加载器负责加载的 classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println("JDK提供的Object类由哪个类加载器加载-->" + classLoader); }
Method:对应类中的方法
    Class clazz = Class.forName("com.java.reflection.Person");  
  
    //1、得到clazz 对应的类中有哪些方法,不能获取private方法  
    Method[] methods = clazz.getMethods();  
    System.out.print("\ngetMethods: ");  
    for (Method method : methods){  
        System.out.print(method.getName() + ", ");  
    }  
  
    //2、获取所有的方法(且只获取当着类声明的方法,包括private方法)  
    Method[] methods2 = clazz.getDeclaredMethods();  
    System.out.print("\ngetDeclaredMethods: ");  
    for (Method method : methods2){  
        System.out.print(method.getName() + ", ");  
    }  
  
    //3、获取指定的方法  
   //第一个参数是方法名,后面的是方法里的参数 
    Method method = clazz.getDeclaredMethod("setName",String.class);
    System.out.println("\nmethod : " + method);  
  
   //第一个参数是方法名,后面的是方法里的参数
    Method method2 = clazz.getDeclaredMethod("setName",String.class ,int.class);
    System.out.println("method2: " + method2);  
  
    //4、执行方法!  
    Object obj = clazz.newInstance();  
    method2.invoke(obj, "draco", 17);  
Methos.invoke()方法:调用Method对象表示的底层方法
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
obj:调用底层方法的对象(调用谁的方法就是用谁的对象)
args:方法调用的参数
Field字段:
 Class clazz = Class.forName("com.java.reflection.Person");  
  
    //1、获取字段  
    //1.1 获取Field的数组,私有字段也能获取  
    Field[] fields = clazz.getDeclaredFields();  
    for (Field field: fields) {  
        System.out.print(field.getName() + ", ");  
    }  
  
    //1.2 获取指定名字的Field(如果是私有的,见下面的4)  
    Field field = clazz.getDeclaredField("name");  
    System.out.println("\n获取指定Field名=: " + field.getName());  
  
    Person person = new Person("draco", 17); 
 
    //2、获取指定对象的Field的值  
    Object val = field.get(person);  
    System.out.println("获取指定对象字段'name'的Field的值=: " + val);  
  
    //3、设置指定对象的Field的值  
    field.set(person, "harry");  
    System.out.println("设置指定对象字段'name'的Field的值=: " + person.name);  
  
    //4、若该字段是私有的,需要调用setAccessible(true)方法  
    Field field2 = clazz.getDeclaredField("age");  
    field2.setAccessible(true);  
    System.out.println("获取指定私有字段名=: " + field2.getName());  
Constructor:构造器
String className = "com.java.reflection.Person"; Class<Person> clazz = (Class<Person>) Class.forName(className); //1.获取Constructor对象 Constructor<Person>[] constructors = (Constructor<Person>[]) Class.forName(className).getConstructors(); for (Constructor<Person> constructor: constructors) { System.out.println(constructor); } Constructor<Person> constructor = clazz.getConstructor(String.class, Integer.class); System.out.println("指定的-->" + constructor); //2.调用构造器的newInstance()方法创建对象 Object obj= constructor.newInstance("ron", 11);
Annotation:注解
Annotation是代码中的特殊标记,可以在编译、类加载、运行时被读取,并执行相应的处理;通过Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入补充信息
Annotation可以象修饰符一样被使用,可用于修饰包、类、构造器、方法、参数、成员变量、局部变量的声明,这些信息被保存在Annotation的“name=value”中
Annotation能用于为程序元素(类、方法、成员变量等)设置元数据
基本的Annotatio:
使用时在前面加@
@override:限定重写父类方法
@Deprecated:用于表示某个程序元素(类、方法等)已过时
@SuppressWarnings:抑制编译器警告
自定义的Annotation:
使用@interface关键字
Annotation的成员变量在Annotation定义中以无参数的形式声明,其方法名和返回值定义了该成员的名字和类型
可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可以使用default关键字
没有成员定义的Annotation称为标记,包含成员变量的Annotation称为元数据Annotation
                    
                
                
            
        
浙公网安备 33010602011771号