Mecanismo de reflexão do resumo da revisão do JavaSE

conceito de reflexão

O conceito de reflexão foi proposto pela primeira vez por Smith em 1982. Refere-se principalmente à capacidade de um programa de acessar, detectar e modificar seu próprio estado ou comportamento, e ajustar ou modificar o comportamento descrito pela aplicação de acordo com o estado e resultado de seu próprio comportamento, estado e semântica associada.

Como funciona a reflexão

Quando o programa estiver em execução, o sistema Java sempre realizará o chamado reconhecimento de tipo de tempo de execução em todos os objetos, que registra a classe a qual cada objeto pertence. Essas informações são acessíveis por meio de aulas especializadas. A classe usada para salvar essas informações é a classe class, que pode manipular arquivos bytecode através do mecanismo de reflexão na linguagem Java

Três maneiras de obter classe

  • A primeira: Class c = Class.forName("nome completo da classe");
  • A segunda: Classe c = object.getClass();
  • O terceiro tipo: Classe c = qualquer type.class;

O que posso fazer com a classe

1. Instancie o objeto

	//不使用反射机制创建对象
	User user = new User();
	System.out.println(user);
	//使用反射机制创建对象
	try {
    
    
		// 通过反射机制,获取Class,通过Class来实例化对象
		Class c = Class.forName("com.bjpowernode.java.bean.User");
		// newInstance()调用的是无参构造,必须保证无参构造是存在的!
		Object obj = c.newInstance();
		System.out.println(obj);
	} catch (Exception e) {
    
    
		e.printStackTrace();
	}

Em segundo lugar, obtenha as propriedades da classe

tipo de retorno nome do método descrever
Fragmento getNome() Obter nome completo da turma
Fragmento getSimpleName() Obter nome de classe curto
Campo[] getCampos() Obter todas as propriedades públicas modificadas em uma classe
Campo[] getDeclaredCampos() Obter todas as propriedades em uma classe
Campo getDeclaredField(Nome da string) Obter propriedade pelo nome da propriedade

Métodos comuns da classe Filed

tipo de retorno nome do método descrever
Fragmento getNome() obter nome do atributo
int getModifiers() O modificador retornado é um número (o codinome do modificador)
Aula getType() Obtenha o tipo de propriedade
public class ReflectTest {
    
    
    public static void main(String[] args) throws Exception{
    
    
        Class studentClass = Class.forName("com.why.java.bean.Student");
        String className = studentClass.getName();
        System.out.println("完整类名:" + className);
        String simpleName = studentClass.getSimpleName();
        System.out.println("简类名:" + simpleName);
        // 获取类中所有的public修饰的Field
        Field[] fields = studentClass.getFields();
        System.out.println(fields.length);
        // 取出这个Field
        Field f = fields[0];
        // 取出这个Field它的名字
        String fieldName = f.getName();
        System.out.println(fieldName);
        // 获取所有的Field
        Field[] fs = studentClass.getDeclaredFields();
        // 遍历
        for(Field field : fs){
    
    
            // 获取属性的修饰符列表
            int i = field.getModifiers(); 
            // 将这个“代号”数字转换成“字符串”吗
            String modifierString = Modifier.toString(i);
            System.out.print(modifierString+" ");
            // 获取属性的类型
            Class fieldType = field.getType();
            String fName = fieldType.getSimpleName();
            System.out.print(fName+" ");
            // 获取属性的名字
            System.out.println(field.getName());
        }
    }
}

【resultado da operação】

完整类名:com.why.java.bean.Student
简类名:Student
private String name
protected int age
 boolean sex
public int no
public static final double MATH_PI

Process finished with exit code 0

3. Acesse as propriedades do objeto

Atribua um valor a um conjunto de propriedades
para obter o valor da propriedade get

public class ReflectTest {
    
    
    public static void main(String[] args) throws Exception{
    
    

        // 不使用反射机制访问一个对象的属性
        Student s = new Student();
        s.no = 1111;
        System.out.println(s.no);

        // 使用反射机制访问一个对象的属性
        Class studentClass = Class.forName("com.why.java.bean.Student");
        Object obj = studentClass.newInstance(); 
        // 获取no属性(根据属性的名称来获取Field)
        Field noFiled = studentClass.getDeclaredField("no");
        // 给obj对象(Student对象)的no属性赋值
        noFiled.set(obj, 22222); // 给obj对象的no属性赋值2222
        // 读取属性的值
        System.out.println(noFiled.get(obj));
        Field nameField = studentClass.getDeclaredField("name");
        // 这样设置完之后,在外部也是可以访问private的。
        nameField.setAccessible(true);
        // 给name属性赋值
        nameField.set(obj, "jackson");
        // 获取name属性的值
        System.out.println(nameField.get(obj));
    }
}

Quarto, o método de obtenção da classe

tipo de retorno nome do método descrever
Método[] getDeclaredMethods() Obtenha todos os métodos, incluindo privado
Método getMethod(String name, Class<?>… parameterTypes) Obter método com base no nome do método e parâmetros formais
Aula[] getParameterTypes() obter tipo de parâmetro
Construtor[] getDeclaredConstructors() Obter todos os construtores
public class ReflectTest {
    
    
    public static void main(String[] args) throws Exception{
    
    
        Class userServiceClass = Class.forName("com.why.java.service.UserService");
        Method[] methods = userServiceClass.getDeclaredMethods();
        // 遍历Method
        for(Method method : methods){
    
    
            // 获取修饰符列表
            System.out.print(Modifier.toString(method.getModifiers())+" ");
            // 获取方法的返回值类型
            System.out.print(method.getReturnType().getSimpleName()+" ");
            // 获取方法名
            System.out.print(method.getName()+"(");
            // 方法的修饰符列表(一个方法的参数可能会有多个。)
            Class[] parameterTypes = method.getParameterTypes();
            for(Class parameterType : parameterTypes){
    
    
                System.out.print(parameterType.getSimpleName()+",");
            }
            System.out.println(")");
        }
    }
}

【resultado da operação】

public void login(int,)
public boolean login(String,String,)
public void logout()

Process finished with exit code 0

Cinco, chame o método do objeto

public class ReflectTest10 {
    
    
    public static void main(String[] args) throws Exception{
    
    
        // 不使用反射机制调用方法
        UserService userService = new UserService();
        boolean loginSuccess = userService.login("admin","123");
        System.out.println(loginSuccess ? "登录成功" : "登录失败");

        // 使用反射机制来调用一个对象的方法
        Class userServiceClass = Class.forName("com.why.java.service.UserService");
        Object obj = userServiceClass.newInstance();
        // 获取Method
        Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
        Object retValue = loginMethod.invoke(obj, "admin","123123");
        System.out.println(retValue);
    }
}

Seis, através do mecanismo de reflexão para chamar o construtor para instanciar o objeto java

public class ReflectTest12 {
    
    
    public static void main(String[] args) throws Exception{
    
    
        // 使用反射机制怎么创建对象
        Class c = Class.forName("com.bjpowernode.java.bean.Vip");
        // 调用无参数构造方法
        Object obj = c.newInstance();
        System.out.println(obj);
        // 调用有参数的构造方法
        // 第一步:先获取到这个有参数的构造方法
        Constructor con = c.getDeclaredConstructor(int.class, String.class, String.class,boolean.class);
        // 第二步:调用构造方法new对象
        Object newObj = con.newInstance(110, "jackson", "1990-10-11", true);
        System.out.println(newObj);

        // 获取无参数构造方法
        Constructor con2 = c.getDeclaredConstructor();
        Object newObj2 = con2.newInstance();
        System.out.println(newObj2);
    }
}

7. Obtenha a classe pai e a interface implementada

tipo de retorno nome do método descrever
Aula getSuperclass() obter classe pai
Aula[] getInterfaces() Obtenha todas as interfaces implementadas
public class ReflectTest13 {
    
    
    public static void main(String[] args) throws Exception{
    
    
        Class stringClass = Class.forName("java.lang.String");
        // 获取String的父类
        Class superClass = stringClass.getSuperclass();
        System.out.println(superClass.getName());
        // 获取String类实现的所有接口
        Class[] interfaces = stringClass.getInterfaces();
        for(Class in : interfaces){
    
    
            System.out.println(in.getName());
        }
    }
}

【resultado da operação】

java.lang.Object
java.io.Serializable
java.lang.Comparable
java.lang.CharSequence
java.lang.constant.Constable
java.lang.constant.ConstantDesc

Process finished with exit code 0

fichário de recursos

Um binder de recursos é fornecido no pacote java.util para facilitar a obtenção do conteúdo no arquivo de configuração de propriedade. Ao usar o método a seguir, o arquivo de configuração de propriedade xxx.properties deve ser colocado no caminho de classe.

arquivo de propriedades

className=java.lang.String
public class ResourceBundleTest {
    
    
    public static void main(String[] args) {
    
    

        // 这个文件必须在类路径下。文件扩展名也必须是properties
        // 并且在写路径的时候,路径后面的扩展名不能写
        //ResourceBundle bundle = ResourceBundle.getBundle("db");

        ResourceBundle bundle = ResourceBundle.getBundle("com/why/java/bean/db");
        String className = bundle.getString("className");
        System.out.println(className);
    }
}

【resultado】

java.lang.String

Process finished with exit code 0

Acho que você gosta

Origin blog.csdn.net/m0_60117382/article/details/123804308
Recomendado
Clasificación