基础的反射机制Java ------学习笔记整理

  • Class类与Java反射

通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法

  1.   getConstructors()
  2.   getConstructor(Class<?>... parameterTypes)
  3.   getDeclaredConstructors()
  4.  getDeclaredConstructor(Class<?>... parameterTypes)

如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。


package com.example.java;

public class Example_01 {
    String s;
    int i,i2,i3;
    /*构造方法(构造函数)
     * 有参构造
     * 
     * 无参构造
     * 
     * 类名与构造方法名相同
     * 
     * 同一类中先执行有参构造再执行无参构造,子类继承父类执行顺序:父类无参数构造》子类无参构造》父类有参数构造》子类无参构造
     * 
     * */
    private Example_01(){
        /*访问修饰符:
         * private     私有控制访问符      被修饰的成员变量仅能被自身访问
         * public      公共访问控制符      所有类都可以访问,但会降低运行安全性和数据的封装性,谨慎使用
         * protected   保护访问控制符       主要是供子类引用,同一包中的其他类也可引用
         * default     缺省默认访问符       没有定义成员变量的修饰符默认为default,可以被本类或同一包中的其他类访问
         * 
         * 非访问修饰符
         * static      静态域修饰符   用static修饰的成员变量仅属于本类的变量,而不属于任何一个具体对象,
         *                       static修饰的成员变量保存在类的公共存储单元,该类任何对象访问它是获取的数据都市相同的,
         *                       该类的任何对象修改它是,都是对同一内存单元进行操作
         * final       最终域修饰符   修饰常量 被它修饰的常量在运行过程中常量的值不可再该变
         * volatile    共享(易失)域修饰符   被它修饰的成员变量可能被几个线程控制和修改,一般用来修饰可接受外部输入的域
         * transient   暂时性域修饰符   修饰暂时性变量
         * */
    }
    protected Example_01(String...strings) throws NumberFormatException{
        //String...strings  定义可变长度的数组
        if(0<strings.length)
            i=Integer.valueOf(strings[0]);
        //Integer类提供了两种构造方法:它们都会返回一个Integer对象
        if(1<strings.length)
            i2=Integer.valueOf(strings[1]);
        if(2<strings.length)
            i3=Integer.valueOf(strings[2]);
        
        
    }
    public void print(){
        System.out.println("s="+s);
        System.out.println("i="+i);
        System.out.println("i2="+i2);
        System.out.println("23="+i3);
    }

}

MAIN类

package com.example.java;

import java.lang.reflect.Constructor;

public class Main_01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//调用Example_01()方法
Example_01 example = new Example_01("10","20","30");
       //访问构造方法
Class<? extends Example_01> exampleC=example.getClass();
//返回Constructor对象的数组,这些对象反映此Class
Constructor[] declaredConstructors =exampleC.getDeclaredConstructors();
//遍历Constructor对象的数组
for(int i=0;i<declaredConstructors.length;i++){
	Constructor<?> constructor=declaredConstructors[i];
    System.out.println("查看是否允许带有可变数量的参数"+constructor.isVarArgs());
    System.out.println("该构造方法的入口参数类型依次为:");
    
    /*java.lang.reflect.Constructor.getParameter();方法返回一个Class对象数组,它以声明顺序表示由此构造方对象表示的构造函数的形式参数类型。
     * 如果底层构造函数没有参数,则返回长度为0的数组。
     * 返回值:此对象表示的构造函数的参数类型。
     * */
    Class[] parameterTypes =constructor.getParameterTypes();
    //循环遍历数组 
    for(int j=0;j<parameterTypes.length;i++){
    	System.out.println(""+parameterTypes[j]);
    }
    System.out.println("该构造方法可能抛出异常的类型为:");
    /*java.lang.reflect.Constructor.getExceptionTypes()方法返回一个Class对象数组,
     * 该对象表示由此构造方对象表示的底层构造函数声明的异常类型。 
     * 如果构造函数在其throws子句中声明没有异常,则返回一个长度为0的数组。
     * 
     * 返回值:声明为由此对象表示的构造函数抛出的异常类型。
     * */
    Class[] exceptionTypes =constructor.getExceptionTypes();
    //遍历数组
    for(int j=0;j<exceptionTypes.length;j++){
    }
    Example_01 example2 =null;
    while(example2 ==null){
    	try{
    		if(i ==2)
    			//创建对象newInstance(); 使用类加载机制创建对象  只能调用无参构造  执行效率低
    			example2 =(Example_01) constructor.newInstance();
    		else if(i==1)
    			example2 =(Example_01)constructor.newInstance("7",5);
    		else{
    			Object[] parameters =new Object[]{new String[]{
    					"100","200","300"}};
    		}
    	}catch(Exception e){
    		System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
    	constructor.setAccessible(true);
    	}
    }
    if(example2!=null){
    	example2.print();
    	System.out.println();
    }
}

	}

}

  • 访问成员变量

通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。每个Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量。

  1.  getFields()
  2.  getField(String name)
  3.   getDeclaredFields()
  4.   getDeclaredField(String name)
  • 访问方法

通过下列一组方法访问方法时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操纵相应的方法

  1. getMethods()
  2. getMethod(String name, Class<?>... parameterTypes)
  3. getDeclaredMethods()
  4.  getDeclaredMethod(String name, Class<?>... parameterTypes)

如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。

  • 使用Annotation的功能

  • 定义Annotation类型
  1. 在定义Annotation类型时,需用定义接口的interface关键字,要在interface关键字前加一个“@”符号,即定义Annotation类型的关键字为@interface,这个关键字的隐含意思是继承了java.lang.annotation.Annotation接口。
  • 访问Annotation信息
  1. 在定义Annotation类型时将@Retention设置为RetentionPolicy.RUNTIME,那么在运行程序时通过反射就可以获取到相关的Annotation信息,如获取构造方法、字段和方法的Annotation信息。
  2. ConstructorFieldMethod均继承了AccessibleObject
  3. isAnnotationPresent(Class<? extends Annotation> annotationClass)用来查看是否添加了指定类型的Annotation,如果是则返回true,否则返回false
  4. getAnnotation(Class<T> annotationClass)用来获得指定类型的Annotation,如果存在则返回相应的对象,否则返回null
  5. 方法getAnnotations()用来获得所有的Annotation,该方法将返回一个Annotation数组。

猜你喜欢

转载自blog.csdn.net/RONG_YAO/article/details/89444760