Java de entrada para o mestre Capítulo 16 reflexão

anuário

reflexiva à base de classe

construtor acesso

variáveis ​​de membro de acesso

Métodos de acesso

Use a função Anotação

definições de tipo de anotação

acesso à informação Anotação


reflexiva à base de classe

java.lang.reflect

Todas as classes herdam da classe Object define um método de classe de objeto getClass, o método retorna um tipo de objeto Class, as informações do objeto usando a classe principal Classe acessível. variáveis ​​e métodos de membros getFields () e GetMethods () método, a fim de obter permissão para o público, incluindo herdada de uma classe pai variáveis ​​e métodos de membros. getDeclaredFields () e getDeclaredMethods () para obter todas as variáveis ​​de membro e métodos definidos em somente a classe.

construtor acesso

O método de construção acedendo a tabela acima, voltar objecto Construtor ou tipo de matriz . Cada objecto representa um construtor Construtor. Cada objecto do construtor pode ser manipulado usando o construtor apropriado.

package ex16_reflect;

public class Example_01 {
    String s;
    int i;
    int i2;
    int i3;

    private Example_01() {
    }

    protected Example_01(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Example_01(String... strings) throws NumberFormatException {
        if (0 < strings.length) {
            i = Integer.valueOf(strings[0]);
        }
        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("i3 = " + i3);
    }
}
//============================================================================

package ex16_reflect;

import java.lang.reflect.Constructor;

public class Main_01 {
    public static void main(String[] args) {
        Example_01 example = new Example_01("10", "20", "30");
        Class<? extends Example_01> exampleC = example.getClass();
        Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();  //获得所有构造方法
        for (int i = 0; i < declaredConstructors.length; i++) {  //遍历所有构造方法
            Constructor<?> constructor = declaredConstructors[i];
            System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());  //是否有可变参数
            
            System.out.println("该构造方法的入口参数类型依次为:");
            Class[] parameterTypes = constructor.getParameterTypes();  //获取所有参数类型
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.println("" + parameterTypes[j]);
            }
            
            System.out.println("该构造方法可能抛出的异常类型为:");
            Class[] exceptionTypes = constructor.getExceptionTypes();  //获取所有异常类型
            for (int j = 0; j < exceptionTypes.length; j++) {
                System.out.println(" " + exceptionTypes[j]);
            }
            
            Example_01 example2 = null;
            while (example2 == null) {
                try {
                    if (i == 2) {
                        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"}};
                        example2 = (Example_01) constructor.newInstance(parameters);
                    }
                } catch (Exception e) {
                    //该构造方法权限为private,默认不允许使用反射利用newInstance()创建对象,先执行setAccessible(true);则允许创建
                    System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");  
                    constructor.setAccessible(true);
                }
            }
            if (example2 != null) {
                example2.print();
                System.out.println();
            }
        }
    }
}

variáveis ​​de membro de acesso

O campo tipo de retorno ou matriz de objectos, cada objeto representa uma variável membro campo , o objecto pode ser manipulado usando Arquivado variável membro correspondente.

package ex16_reflect;

public class Example_02 {
    int i;
    public float f;
    protected boolean b;
    private String s;
}

//=========================================================

package ex16_reflect;

import java.lang.reflect.Field;

public class Main_02 {
    public static void main(String[] args) {
        Example_02 example = new Example_02();
        Class exampleC = example.getClass();  //使用getClass()获得Class对象
        Field[] declaredFields = exampleC.getDeclaredFields();  //获得所有成员变量
        for (int i = 0; i < declaredFields.length; i++) {
            Field field = declaredFields[i];  //遍历成员变量
            System.out.println("名称为:" + field.getName());  //获取成员变量名称
            Class fieldType = field.getType();
            System.out.println("类型为:" + fieldType);  //获取成员变量类型

            boolean isTrue = true;
            while (isTrue) {
                //如果该成员变量的访问权限为private,则抛出异常,则不允许访问
                try {
                    isTrue = false;
                    System.out.println("修改前的值:" + field.get(example));

                    if (fieldType.equals(int.class)) {  //判断变量类型是否是int类型
                        System.out.println("利用方法setInt()修改成员变量的值");
                        field.setInt(example, 168);
                    } else if (fieldType.equals(float.class)) {  //判断变量类型是否是float类型
                        System.out.println("利用方法setFloat()修改成员变量的值");
                        field.setFloat(example, 99.9F);
                    } else if (fieldType.equals(boolean.class)) {
                        System.out.println("利用方法setBoolean()修改成员变量的值");
                        field.setBoolean(example, true);
                    } else {
                        System.out.println("利用方法set()修改成员变量的值");
                        field.set(example, "MWQ");  //可以为各种类型的成员变量赋值
                    }
                    System.out.println("修改后的值:" + field.get(example));
                } catch (Exception e) {
                    //String s;权限为private,需要先设置setAccessible()再修改
                    System.out.println("在设置成员变量时抛出异常,下面执行setAccessible()方法");
                    field.setAccessible(true);
                    isTrue = true;
                }
            }
            System.out.println("---------------------------");
        }


        Field field = declaredFields[3];
        try {
            field.set(example, "hi");
            System.out.println(field.get(example));
            field.setAccessible(false);  //修改过一次后就一直是true了
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

Métodos de acesso

Através getMethod () método de acesso e outros métodos, Método, matriz de retorno () e um tipo de objecto. Cada objecto representa um método do Método. Método objecto pode ser manipulado por um método correspondente.

package ex16_reflect;

public class Example_03 {
    static void staticMethod() {
        System.out.println("执行staticMethod()方法");
    }

    public int publicMethod(int i) {
        System.out.println("执行publicMethod()方法");
        return i * 100;
    }

    protected int protectedMethod(String s, int i) throws NumberFormatException {
        System.out.println("执行protectedMethod()方法");
        return Integer.valueOf(s) + i;
    }

    private String privateMethod(String... strings) {
        System.out.println("执行privateMethod()方法");
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < strings.length; i++) {
            stringBuffer.append(strings[i]);
        }
        return stringBuffer.toString();

    }
}
//============================================================

package ex16_reflect;

import java.lang.reflect.Method;

public class Main_03 {
    public static void main(String[] args) {
        Example_03 example = new Example_03();
        Class exampleC = example.getClass();
        Method[] declaredMethods = exampleC.getDeclaredMethods();  //获取所有方法
        for (int i = 0; i < declaredMethods.length; i++) {
            Method method = declaredMethods[i];  //遍历方法
            System.out.println("名称为:" + method.getName());  //获取方法名称

            System.out.println("是否允许带有可变数量的参数:" + method.isVarArgs());  //是否有可变参数

            System.out.println("入口参数类型依次为:");  //入口参数类型
            Class[] parameterTypes = method.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.println(" " + parameterTypes[j]);
            }

            System.out.println("返回值类型:" + method.getReturnType());  //返回值类型

            System.out.println("可能抛出的异常:");
            Class[] exceptionTypes = method.getExceptionTypes();  //可能抛出的异常类型
            for (int j = 0; j < exceptionTypes.length; j++) {
                System.out.println(" " + exceptionTypes[j]);
            }

            boolean isTrue = true;
            while (isTrue) {
                //如果方法访问权限为private抛出异常,不允许访问
                try {
                    isTrue = false;
                    if ("staticMethod".equals(method.getName())) {
                        method.invoke(example);  //执行没有入口参数的方法staticMethod
                    } else if ("publicMethod".equals(method.getName())) {
                        System.out.println("返回值为:"
                                + method.invoke(example, 168));  //执行方法
                    } else if ("protectedMethod".equals(method.getName())) {
                        System.out.println("返回值为:"
                                + method.invoke(example, "7", 5));  //执行方法
                    } else if ("privateMethod".equals(method.getName())) {
                        Object[] parameters = new Object[]{new String[]{"M", "W", "Q"}};  //定义二维数组
                        System.out.println("返回值为:"
                                + method.invoke(example, parameters)); //执行方法
                    }

                } catch (Exception e) {
                    //privateMethod()权限为private需要先setAccessible(true);才可以访问
                    System.out.println("在执行方法时出现异常,执行下面的setAccessible()方法");
                    method.setAccessible(true);
                    isTrue = true;
                }
            }
            System.out.println();
        }
    }
}

Use a função Anotação

definições de tipo de anotação

  • Use @ interface, o significado implícito desta palavra-chave é herdada java.lang.annotation.Annotation interface
  • Use @Annotation, definir o tipo de membros elemento tipo de anotação utilizado, o uso do conjunto de enumeração constante de enumeração ElementType classe
  • @Retention utilizadas, desde anotação gama eficaz, constante enumeração é definido na classe RetentionPolicy enumeração

package ex16_reflect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)  //用于构造方法
@Retention(RetentionPolicy.RUNTIME)  //在运行时加载Annotation到JVM中
public @interface Constructor_Annotation {
    String value() default "默认构造方法";  //定义一个具有默认值的String型成员
}
package ex16_reflect;

import java.lang.annotation.*;
//用于字段、方法、参数
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})

//在运行时加载Annotation到JVM中
@Retention(RetentionPolicy.RUNTIME)

public @interface Field_Method_Parameter_Annotation {
    String describle();               //定义一个没有默认值的String型成员
    Class type() default void.class;  //定义一个具有默认值的Class型成员
}

acesso à informação Anotação

Ao definir o tipo de anotação, @ retenção RetentionPolicy.RUNTIME conjunto, em seguida, o programa é executado por reflexão pode ser obtida informação relacionada anotações, tais como métodos de anotação informações de configuração que adquirem, campos, métodos.

  • classe construtor, Campo, Método AccessableObject são herdadas, três métodos são definidos na anotação na AccessibleObject
    • isAnnotationPresent (Class <? estende Anotação> annotationClass); ver se a adição do tipo de anotação especificada
    • getAnnotation (Classe <T> annotationClass); a anotação para o tipo especificado, devolve o objecto correspondente está presente, não há nenhuma nulo retorno
    • GetAnnotations (); retornar todos anotação, retorna uma matriz
  • Método no construtor e também define os métodos getParameterAnnotations (); anotação adicionado para obter todos os parâmetros, retornará anotação de tipo matriz bi-dimensional, na mesma ordem como ordem de declaração na matriz, não há parâmetros de comprimento 0 é retornado matriz; n anotação matriz aninhada de parâmetro comprimento espaço reservado 0

Usando o previamente definido no @Constructor_Annotation classe Record Tipo Anotação e @Field_Method_Parameter_Annotation.

package ex16_reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Record {
    @Field_Method_Parameter_Annotation(describle = "编号", type = int.class)
    int id;
    @Field_Method_Parameter_Annotation(describle = "姓名", type = String.class)
    String name;

    @Constructor_Annotation()
    public Record() {
    }

    @Constructor_Annotation("立即初始化构造方法")
    public Record(
            @Field_Method_Parameter_Annotation(describle = "编号", type = int.class) int id,
            @Field_Method_Parameter_Annotation(describle = "姓名", type = String.class) String name) {
        this.id = id;
        this.name = name;
    }

    @Field_Method_Parameter_Annotation(describle = "获得编号", type = int.class)
    public int getId() {
        return id;
    }

    @Field_Method_Parameter_Annotation(describle = "设置编号")
    public void setId(
            @Field_Method_Parameter_Annotation(describle = "编号", type = int.class) int id) {
        this.id = id;
    }

    @Field_Method_Parameter_Annotation(describle = "获得姓名", type = String.class)
    public String getName() {
        return name;
    }

    @Field_Method_Parameter_Annotation(describle = "设置姓名")
    public void setName(
            @Field_Method_Parameter_Annotation(describle = "姓名", type = String.class) String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Record record = new Record();
        Class recordC = record.getClass();

        //========================访问构造方法(Constructor)====================================
        System.out.println("=====访问构造方法(Constructor)=======");
        Constructor[] declaredConstructors = recordC.getDeclaredConstructors();  //获得所有构造方法
        for (int i = 0; i < declaredConstructors.length; i++) {  //遍历构造方法
            Constructor constructor = declaredConstructors[i];
            //判断是否是指定类型的注释
            if (constructor.isAnnotationPresent(Constructor_Annotation.class)) {
                //获取指定类型的注释
                Constructor_Annotation ca = (Constructor_Annotation) constructor
                        .getAnnotation(Constructor_Annotation.class);
                System.out.println(ca.value());   //获得注释信息
            }
            //获得参数的注释
            Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
            for (int j = 0; j < parameterAnnotations.length; j++) {
                //获得指定参数注释的长度
                int length = parameterAnnotations[j].length;
                if (length == 0) {  //长度为0表示没有为该参数添加注释
                    System.out.println("未添加Annotation的参数");
                } else {
                    for (int k = 0; k < length; k++) {
                        //获得参数的注释
                        Field_Method_Parameter_Annotation pa =
                                (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
                        System.out.println("  " + pa.describle());  //获得参数描述
                        System.out.println("  " + pa.type());       //获得参数类型
                    }
                }
            }
            System.out.println();
        }

        //============================访问字段(Field)=====================================
        System.out.println("=======访问字段(Field)==========");
        Field[] declaredFileds = recordC.getDeclaredFields();  //获得所有字段
        for (int i = 0; i < declaredFileds.length; i++) {
            Field field = declaredFileds[i];
            //查看是否具有指定类型的注释
            if (field.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
                //获得指定类型的注释
                Field_Method_Parameter_Annotation fa = field
                        .getAnnotation(Field_Method_Parameter_Annotation.class);
                System.out.println("  " + fa.describle());  //获得字段的描述
                System.out.println("  " + fa.type());       //获得字段的类型
            }
            System.out.println();
        }

        //============================访问方法(Method)及包含参数的Annotation信息================
        System.out.println("===访问方法(Method)及包含参数的Annotation信息===");
        Method[] methods = recordC.getDeclaredMethods();  //获得所有方法
        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            //查看是否有指定类型的注释
            if (method.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {
                //获得指定类型的注释
                Field_Method_Parameter_Annotation ma = method
                        .getAnnotation(Field_Method_Parameter_Annotation.class);
                System.out.println("  " + ma.describle());  //获得方法的描述
                System.out.println("  " + ma.type());       //获得方法的返回值类型
            }
            //获得参数的注释
            Annotation[][] parameterAnnotations = method
                    .getParameterAnnotations();
            for (int j = 0; j < parameterAnnotations.length; j++) {
                int length = parameterAnnotations[j].length;
                if (length == 0) {
                    System.out.println("未添加Annotation的参数");
                } else {
                    for (int k = 0; k < length; k++) {
                        //获得指定类型的注释
                        Field_Method_Parameter_Annotation pa =
                                (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
                        System.out.println("  " + pa.describle());  //获得参数描述
                        System.out.println("  " + pa.type());       //获得参数类型
                    }
                }
            }
            System.out.println();

        }

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

Publicado 46 artigos originais · ganhou elogios 0 · Vistas 1019

Acho que você gosta

Origin blog.csdn.net/weixin_37680513/article/details/103560581
Recomendado
Clasificación