反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力, 并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
程序运行时,Java系统会一直对所有对象进行所谓的运行时类型识别,这项信息记录了每个对象所属的类。通过专门的类可以访问这些信息。用来保存这些信息的类是class 类,通过Java语言中的反射机制可以操作字节码文件
//不使用反射机制创建对象
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();
}
返回类型 | 方法名 | 描述 |
---|---|---|
String | getName() | 获取完整类名 |
String | getSimpleName() | 获取简类名 |
Field[] | getFields() | 获取类中所有的public修饰的属性 |
Field[] | getDeclaredFields() | 获取类中所有的属性 |
Field | getDeclaredField(String name) | 根据属性名获取属性 |
Filed类常用方法
返回类型 | 方法名 | 描述 |
---|---|---|
String | getName() | 获取属性名 |
int | getModifiers() | 返回的修饰符是一个数字(修饰符的代号) |
Class | getType() | 获取属性的类型 |
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());
}
}
}
【运行结果】
完整类名: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
给属性赋值set
获取属性的值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));
}
}
返回类型 | 方法名 | 描述 |
---|---|---|
Method[] | getDeclaredMethods() | 获取所有的方法包括私有 |
Method | getMethod(String name, Class<?>… parameterTypes) | 根据方法名和形参获取方法 |
Class[] | getParameterTypes() | 获取形参类型 |
Constructor[] | getDeclaredConstructors() | 获取所有的构造方法 |
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(")");
}
}
}
【运行结果】
public void login(int,)
public boolean login(String,String,)
public void logout()
Process finished with exit code 0
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);
}
}
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);
}
}
返回类型 | 方法名 | 描述 |
---|---|---|
Class | getSuperclass() | 获取父类 |
Class[] | getInterfaces() | 获取实现的所有接口 |
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());
}
}
}
【运行结果】
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
java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。
properties文件
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);
}
}
【结果】
java.lang.String
Process finished with exit code 0
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/m0_60117382/article/details/123804308
内容来源于网络,如有侵权,请联系作者删除!