参考:https://www.cnblogs.com/ysocean/p/6516248.html
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。(来自 https://www.jianshu.com/p/9be58ee20dee)
class Person{
private int age = 11;
public String name = "csc";
public Person(){
}
private void doSomething(){
System.out.println("do some thing");
}
public String getName(){
return name;
}
@Override
public String toString() {
return "toString() : Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
/*方式1*/
Person person = new Person();
Class class1 = person.getClass();
/*方式2*/
Class class2 = Person.class; //该方法最为安全可靠,程序性能更高
/*方式3*/
Class class3 = null;
try {
class3 = Class.forName("test.testReflex.Person"); //通过 Class 对象的 forName() 静态方法来获取,用的最多.但可能抛出 ClassNotFoundException 异常
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/*一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的 c1,c2,c3进行 equals 比较,发现都是true*/
System.out.println(class1 == class2); //true
System.out.println(class2 == class3); //true
System.out.println(class1 == class3); //true
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
部分参考 https://www.jianshu.com/p/9be58ee20dee
public class ReflexDemo1 {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException, InstantiationException {
getClass3Method();
testReflexMethod();
}
/*三种获取class的方法*/
private static void getClass3Method(){
/*方式1*/
Person person = new Person();
Class class1 = person.getClass();
/*方式2*/
Class class2 = Person.class; //该方法最为安全可靠,程序性能更高
/*方式3*/
Class class3 = null;
try {
class3 = Class.forName("test.testReflex.Person"); //通过 Class 对象的 forName() 静态方法来获取,用的最多.但可能抛出 ClassNotFoundException 异常
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/*一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的 c1,c2,c3进行 equals 比较,发现都是true*/
System.out.println(class1 == class2); //true
System.out.println(class2 == class3); //true
System.out.println(class1 == class3); //true
}
private static void testReflexMethod() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class personClass = Person.class;
System.out.println("1.类名称~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
String className = personClass.getName();
System.out.println("className : "+className);
System.out.println();
System.out.println("2.类的public类型的属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获得public类型的属性*/
Field[] fields = personClass.getFields();
for(Field field : fields){
System.out.println(field.getName());
}
System.out.println();
System.out.println("3.类的所有属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获得类的所有属性,包括private*/
Field[] allFields = personClass.getDeclaredFields();
for(Field field : allFields){
System.out.println(field.getName());
}
System.out.println();
System.out.println("4.public类型的方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获得public类型的方法*/
Method[] methods = personClass.getMethods();
for(Method method : methods){
System.out.println(method.getName());
}
System.out.println();
System.out.println("5.类中的所有方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获得类中的所有方法*/
Method[] allMethods = personClass.getDeclaredMethods();
for(Method method : allMethods){
System.out.println(method.getName());
}
System.out.println();
System.out.println("6.获取指定的属性name~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获取指定的属性*/
Field name = personClass.getField("name");
System.out.println(name.getClass()+" | "+name);
System.out.println();
System.out.println("7.获取指定的私有属性age~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
/*获取指定的私有属性*/
Field age = personClass.getDeclaredField("age");
//启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
age.setAccessible(true);
System.out.println(age.getClass()+" | "+age);
System.out.println();
/*创建一个对象*/
Object person = personClass.newInstance();
/*将person对象的age属性设置成 12*/
age.set(person,12);
System.out.println("8.person对象的age属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
//使用反射机制可以打破封装性,导致了java对象的属性不安全。
System.out.println(age.get(person));
System.out.println();
System.out.println("9.获取构造方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Constructor[] constructors = personClass.getConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor.toString());
}
System.out.println();
}
}
class Person{
private int age = 11;
public String name = "csc";
public Person(){
}
private void doSomething(){
System.out.println("do some thing");
}
public String getName(){
return name;
}
@Override
public String toString() {
return "toString() : Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
输出:
true
true
true
1.类名称~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
className : test.testReflex.Person
2.类的public类型的属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
name
3.类的所有属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
age
name
4.public类型的方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
toString
getName
wait
wait
wait
equals
hashCode
getClass
notify
notifyAll
5.类中的所有方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
toString
getName
doSomething
6.获取指定的属性name~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class java.lang.reflect.Field | public java.lang.String test.testReflex.Person.name
7.获取指定的私有属性age~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class java.lang.reflect.Field | private int test.testReflex.Person.age
8.person对象的age属性~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
9.获取构造方法~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public test.testReflex.Person()
示例代码:
public class ReflexDemo2 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class sonClass = Class.forName("test.testReflex.Son");
Object son = sonClass.newInstance();
/*son 获取privateField变量的值*/
Field field = getFieldValue(son,"privateField");
System.out.println(field.get(son));
}
public static Field getFieldValue(Object son , String fieldName){
/*1.获取fieldName对应的Field*/
Field field = null;
Class c = son.getClass();
while(c != Object.class){
try {
field = c.getDeclaredField(fieldName);
field.setAccessible(true);
System.out.println(c.getName()+"中有"+fieldName+"字段");
return field;
} catch (NoSuchFieldException e) {
System.out.println(c.getName()+"中没有"+fieldName+"字段");
}finally {
c = c.getSuperclass();
if(c != Object.class){
continue;
}
}
}
return null;
}
}
class Father{
public String publicField = "parent_publicField";
protected String protectedField = "parent_protectedField";
String defaultField = "parent_defaultField";
private String privateField = "parent_privateField";
}
class Son extends Father{
}
输出
test.testReflex.Son中没有privateField字段
test.testReflex.Father中有privateField字段
parent_privateField
实体类
public class Entity {
private static String TEST = "TEST";
private String name;
private int id;
public Entity(){
}
private Entity(String name, int id) {
this.name = name;
this.id = id;
}
private String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Entity{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
private int MethodA(Integer index){
return index;
}
}
测试反射类
public class ReflexDemo3 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
createEntity();
reflexConstructor();
reflexPrivateAttr();
reflexPrivateMethod();
}
/*创建对象*/
public static void createEntity() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
System.out.println("创建对象示例 : ");
Class entityClass = Class.forName("test.testReflex.Entity");
/*要使用entityClass.newInstance(),那么Entity中就要参数列表是空的构造方法*/
Object object = entityClass.newInstance();
Entity entity = (Entity)object;
entity.setId(1);
entity.setName("me");
System.out.println(entity.toString());
}
/*反射私有构造方法*/
public static void reflexConstructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
System.out.println("反射私有构造方法 : ");
Class entityClass = Class.forName("test.testReflex.Entity");
Constructor constructor = entityClass.getDeclaredConstructor(String.class,int.class);
/*注意这里是要设置accessible*/
constructor.setAccessible(true);
/*这里使用的newInstance方法*/
Object object = constructor.newInstance("two",11);
System.out.println(((Entity)object).toString());
}
/*反射私有属性*/
public static void reflexPrivateAttr() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
System.out.println("反射私有属性:");
Class entityClass = Class.forName("test.testReflex.Entity");
Field field = entityClass.getDeclaredField("TEST");
field.setAccessible(true);
/*要使用entityClass.newInstance(),那么Entity中就要参数列表是空的构造方法*/
Object object = entityClass.newInstance();
System.out.println(field.get(object));
}
/*反射私有方法*/
public static void reflexPrivateMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
System.out.println("反射私有方法:");
Class entityClass = Class.forName("test.testReflex.Entity");
Method method = entityClass.getDeclaredMethod("MethodA", Integer.class);
method.setAccessible(true);
/*要使用entityClass.newInstance(),那么Entity中就要参数列表是空的构造方法*/
Object object = entityClass.newInstance();
/*invoke参数第一个表示对象,后面是参数列表*/
int result = (int) method.invoke(object,1);
System.out.println(result);
}
}
输出
创建对象示例 :
Entity{name='me', id=1}
反射私有构造方法 :
Entity{name='two', id=11}
反射私有属性:
TEST
反射私有方法:
1