Diretório de artigos
- conceito de reflexão
- Como funciona a reflexão
- Três maneiras de obter classe
- O que posso fazer com a classe
-
- 1. Instancie o objeto
- Em segundo lugar, obtenha as propriedades da classe
- 3. Acesse as propriedades do objeto
- Quarto, o método de obtenção da classe
- Cinco, chame o método do objeto
- Seis, através do mecanismo de reflexão para chamar o construtor para instanciar o objeto java
- 7. Obtenha a classe pai e a interface implementada
- fichário de recursos
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