概念
- 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
- 反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!
- 反射的作用是通过反射机制访问java对象的属性,方法,构造方法等。
类说明
1.Java反射机制提供的类
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
其中Class是类的类型,Constructor是构造类型,Field是属性类型,Method是方法类型,Modifier是修饰符类型
2.自定义的类
com.blue.User
其中User类的源码是:
public class User implements Serializable {
private String name;
private String password;
private int age;
private int level;
private String email;
protected String tel;
public String desc;
public User() {
System.out.println("调用 public User()");
}
public User(String name, String password) {
System.out.println("调用 public User(String name, String password)");
this.name = name;
this.password = password;
}
public User(String name, String password, int age) {
System.out.println("调用 public User(String name, String password, int age)");
this.name = name;
this.password = password;
this.age = age;
}
private User(String email){
System.out.println("调用 private User(String email)");
}
protected User(String name,String password,String email,String tel){
System.out.println("调用 protected User(String name,String password,String email,String tel)");
}
public User(String name, String password, int age, int level, String email, String tel, String desc) {
this.name = name;
this.password = password;
this.age = age;
this.level = level;
this.email = email;
this.tel = tel;
this.desc = desc;
}
public String getDesc() {
System.out.println("getDesc");
return desc;
}
public int getLevel() {
System.out.println("getLevel");
return level;
}
public String method_public(){
return "public String method_public()";
}
public String method_public(String param){
return "public String method_public(String param)";
}
public String method_public(int level){
return "public String method_public(int level)";
}
protected String method_protected(){
return "protected String method_protected()";
}
private String method_private(){
return " private String method_private()";
}
private String method_private(String params){
return "private String method_private(String params)";
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
", age=" + age +
", level=" + level +
", email='" + email + '\'' +
", tel='" + tel + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
方法说明
获取方法,属性、构造方法、类和接口,不再详细描述,只来看一下关键字:
方法关键字 | 含义 |
---|---|
getDeclaredMethods() | 获取所有的方法 |
getReturnType() | 获得方法的放回类型 |
getParameterTypes() | 获得方法的传入参数类型 |
getDeclaredMethod("方法名",参数类型.class,……) | 获得特定的方法 |
属性关键字: | 含义 |
---|---|
getDeclaredFields | 获取所有属性 |
getDeclaredField("属性名") | 获取某个属性 |
getField("属性名") | 获取某个公有属性 |
构造关键字: | 含义 |
---|---|
getDeclaredConstructors() | 获取所有的构造方法 |
getDeclaredConstructor(参数类型.class,……) | 获取特定的构造方法 |
父类和父接口 | 含义 |
---|---|
getSuperclass() | 获取某类的父类 |
getInterfaces() | 获取某类实现的接口 |
具体实现
功能实现代码用到了junit包,lz用的是junit 4.12,有需要的可以下载junit4.12验证。功能实现代码如下:
package com.blue;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.*;
public class ReflectDemo {
private String className;
private Class userClass;
@Before
public void init() throws ClassNotFoundException {
//需要反射的包名和类名
className = "com.blue.User";
userClass = Class.forName(className);
// /**
// * 获取类有三种方式
// */
//
// //第一种方式:
// Class userClass1 = Class.forName("com.blue.User");
// //第二种方式:
// //java中每个类型都有class 属性.
// Class userClass2 = User.class;
//
// //第三种方式:
// //java语言中任何一个java对象都有getClass 方法
// //c3是运行时类 (e的运行时类是Employee)
// Class userClass3 = new User().getClass();
}
/**
* 获取类名字
*/
@Test
public void getClassName(){
System.out.println(userClass.getName());
}
/**
* 获得构造方法
* @throws Exception
*/
@Test
public void getConstructors() throws Exception {
/*
获取所有public构造方法
*/
System.out.println("public构造参数列表");
Constructor[] constructors01 = userClass.getConstructors();
for (Constructor constructor:constructors01) {
System.out.println(constructor);
}
/*
获取所有构造方法,包括私有方法和受保护的方法
*/
System.out.println("private构造参数列表");
Constructor[] constructors02 = userClass.getDeclaredConstructors();
for (Constructor constructor:constructors02) {
System.out.println(constructor);
}
//两个String的有参构造
System.out.println("两个String的有参构造");
Constructor constructor01 = userClass.getConstructor(String.class,String.class);
System.out.println(constructor01);
constructor01.newInstance("user01","123456");
//无参构造
System.out.println("无参构造");
Constructor constructor02 = userClass.getConstructor();
System.out.println(constructor02);
constructor02.newInstance();
System.out.println("私有有参构造");
Constructor constructor03 = userClass.getDeclaredConstructor(String.class);
System.out.println(constructor03);
//private和protected外部无法直接调用,关掉权限的验证
constructor03.setAccessible(true);
constructor03.newInstance("123456@qq.com");
}
/**
* 获得所有字段
* @throws Exception
*/
@Test
public void getField() throws Exception {
//获得所有public的字段
System.out.println("所有public的字段");
Field[] fields01 = userClass.getFields();
for (Field field:fields01) {
System.out.println(field);
}
//获得所有的字段
System.out.println("获得所有的字段");
Field[] fields02= userClass.getDeclaredFields();
for (Field field:fields02) {
System.out.println(field);
}
User user = new User("user01", "123456", 18, 1,"123456@qq.com", "13888888888", "测试数据");
System.out.println("单独获取某个字段");
Field field01 = userClass.getField("desc");
System.out.println(field01);
String fieldValue01 = (String)field01.get(user);
System.out.println(fieldValue01);
field01.set(user,"测试数据被修改");
System.out.println(user);
Field field02 = userClass.getDeclaredField("name");
System.out.println(field02);
field02.setAccessible(true);
String fieldValue02 = (String)field02.get(user);
System.out.println(fieldValue02);
field02.set(user,"lisi");
System.out.println(user);
Field field03 = userClass.getDeclaredField("level");
System.out.println(field03);
field03.setAccessible(true);
int fieldValue03 = (Integer) field03.get(user);
System.out.println(fieldValue03);
field03.set(user,2);
System.out.println(user);
}
/**
* 获得所有方法
*/
@Test
public void getMethod() throws Exception{
//获得所有public方法,包括集成的方法
System.out.println("所有public方法");
Method[] methods01 = userClass.getMethods();
for(Method method:methods01){
System.out.println(method);
}
//获得所有方法,包括私有的和受保护的,但是不包括继承的方法
System.out.println("所有方法(不包括继承的方法)");
Method[] methods02 = userClass.getDeclaredMethods();
for(Method method:methods02){
System.out.println(method);
}
User user = new User();
//调用公有无参方法
System.out.println("调用公有无参方法");
Method method01 = userClass.getMethod("method_public");
System.out.println(method01);
Object return01 = method01.invoke(user);
System.out.println(return01);
//调用公有有参方法
System.out.println("调用公有有参方法");
Method method02 = userClass.getMethod("method_public",String.class);
System.out.println(method02);
Object return02 = method02.invoke(user,"my params");
System.out.println(return02);
Method method03 = userClass.getMethod("method_public",int.class);
System.out.println(method03);
Object return03 = method03.invoke(user,1);
System.out.println(return03);
//获得私有方法
System.out.println("获得私有方法");
Method method04 = userClass.getDeclaredMethod("method_private");
System.out.println(method04);
method04.setAccessible(true);
Object return04 = method04.invoke(user);
System.out.println(return04);
Method method05 = userClass.getDeclaredMethod("method_protected");
System.out.println(method05);
method05.setAccessible(true);
Object return05 = method05.invoke(user);
System.out.println(return05);
//调用带参数私有方法
System.out.println("调用带参数私有方法");
Method method06 = userClass.getDeclaredMethod("method_private",String.class);
System.out.println(method06);
method06.setAccessible(true);
Object return06 = method06.invoke(user,"my params");
System.out.println(return06);
}
/**
* 获取实现的接口
*/
@Test
public void getInterface(){
Class[] interfaces = userClass.getInterfaces();
for(Class cls:interfaces){
System.out.println(cls);
}
}
/**
* 获取超类(父类)
*/
@Test
public void getSuperClass(){
Type type = userClass.getGenericSuperclass();
System.out.println(type);
}
}