Java反射
Posted 364.99°
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java反射相关的知识,希望对你有一定的参考价值。
Java代码运行:
1.反射
反射机制——将类的各个部分封装成其他对象
反射作用——可以在程序运行过程中,操作这些对象
可以解耦,提高程序的可扩展性
1.1 获取Class对象的方法
♦ Class.forName("完整类名")
将字节码文件加载进内存,返回Class对象
多用于配置文件中——读取文件,加载类
♦ 类名.class
通过类名的属性class获取
多用于参数的传递
♦ 对象.getClass()
getClass()是Object类中定义的方法
多用于对象的获取字节码的方式
package com.study.web.reflect;
public class ReflectRole {
public static void main(String[] args) throws Exception {
//Class.forname("完整类名")
Class class1 = Class.forName("com.study.web.reflect.Role");
System.out.println(class1);
//类名.class
Class class2 = Role.class;
System.out.println(class2);
//对象.getClass()
Role role = new Role();
Class class3 = role.getClass();
System.out.println(class3);
//判断获取的三个Class对象是否相等
System.out.print("class1 == class2 --> ");
System.out.println(class1==class2);
System.out.print("class2 == class3 --> ");
System.out.println(class2==class3);
}
}
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,三种方法中任意一种获取的Class对象都是同一个
1.2 Class功能/方法
♦ 获取成员变量
Filed[] getFields()
Field getField(String name)
Filed[] getDeclaredFields()
Filed getDeclaredField(String name)
♦ 获取构造方法
Constructor<?>[] getConstructors()
Constructor<T> getConstructors(类<?>...parameterTypes)
Constructor<T> getDeclaredConstructors(类<?>...parameterTypes)
Constructor<?>[] getDeclaredConstructors()
♦ 获取成员方法
Method[] getMethods()
Method getMethod(String name,类<?>...parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?>...parameterTypes)
♦ 获取类名
String getName()
Role类
public class Role {
private int id;
private String name;
public int age;
public String gender;
//构造器
public Role() {
}
public Role(String name) {
this.name = name;
}
public Role(int id) {
this.id = id;
}
public Role(int id, String name) {
this.id = id;
this.name = name;
}
//setter
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
//getter
public int getId() {
return id;
}
public String getName() {
return name;
}
}
//toString
@Override
public String toString() {
return "Role{" +
"id=" + id +
", name='" + name + '\\'' +
'}';
}
//无参成员方法
public void say(){
System.out.println("say...");
}
//有参成员方法
public void eat(String food){
System.out.println("eat..."+food);
}
获取成员变量
package com.study.web.reflect;
import java.lang.reflect.Field;
import java.util.Arrays;
public class ReflectRole1 {
public static void main(String[] args) throws Exception {
//获取Class对象
Class roleClass = Role.class;
/*
成员变量:
设置值
获取值
*/
//Field[] getFields()——public修饰的成员变量
Field[] fields1 = roleClass.getFields();
System.out.println(Arrays.toString(fields1));
//Field getField(String name)
Field field1 = roleClass.getField("gender");
//获取成员变量的值
Role role = new Role();
Object value = field1.get(role);
System.out.println(value);
//设置成员变量的值
field1.set(role,"张三");
System.out.println(role);
//Filed[] getDeclaredFields()——获取所有的成员变量(无视修饰符)
Field[] fields2 = roleClass.getDeclaredFields();
System.out.println(Arrays.toString(fields2));
//Filed getDeclaredField(String name)
//直接访问私有的会报错
Field field2 = roleClass.getDeclaredField("id");
//忽略访问权限修饰符的安全检查
field2.setAccessible(true);//暴力反射
System.out.println(field2);
}
}
获取构造方法
//Constructor<T>[] getConstructors(类<?>...parameterTypes)
Constructor constructor = roleClass.getConstructor(int.class,String.class);
System.out.println(constructor);
//创建对象——有参
Object role1 = constructor.newInstance(001,"张三");
System.out.println(role1);
//创建对象——无参
Object role2 = roleClass.newInstance();
获取成员方法
//Method getMethod(String name,类<?>...parameterTypes)
Method say_Method = roleClass.getMethod("say");
Method eat_Method = roleClass.getMethod("eat",String.class);
//invoke——执行方法
say_Method.invoke(role1);
eat_Method.invoke(role1,"fish");
//Method[] getMethods()——除了类中定义的方法,还会输出Object的方法
Method[] methods = roleClass.getMethods();
System.out.println(Arrays.toString(methods));
//获取方法名
for (Method method:methods){
String name =method.getName();
System.out.println(name);
}
获取类名
//String getName()——获取类名(全类名)
System.out.println(roleClass.getName());
2.案例
新建配置文件ReflectDemo.properties
className=com.study.web.reflect.Role
methodName1=say
methodName2=eat
反射测试类
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
/*
不改变改类的任何代码的前提下,可以创建任意类的对象,可以执行任意方法
方案:
配置文件+反射
步骤:
将需要创建的对象的全类名和需要执行的方法定义在配置文件中
在程序中加载读取配置文件
创建对象
执行方法
*/
//1.加载配置文件
//创建properties对象
Properties properties = new Properties();
/*
加载配置文件,转换为一个集合
获取class目录下的配置文件
*/
ClassLoader classLoader = ReflectDemo.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("ReflectDemo.properties");
properties.load(inputStream);
//2.获取配置文件中定义的数据
String className = properties.getProperty("className");
String methodName1 = properties.getProperty("methodName1");
String methodName2 = properties.getProperty("methodName2");
//3.加载改类进内存
Class clasz = Class.forName(className);
//4.创建对象
Object obj = clasz.newInstance();
//5.获取方法对象
Method method1 = clasz.getMethod(methodName1);
Method method2 = clasz.getMethod(methodName2,String.class);
//6.执行方法
method1.invoke(obj);
method2.invoke(obj,"noodle");
}
}
以上是关于Java反射的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)