什么是反射?
Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。
反射的三种方式:
方式一:利用对象获取类--------------不推荐(已经获取到对象,再用反射意义不大)
public static void main(String[] args) { Person person = new Person(); Class<?> c = person.getClass(); System.out.println(c.getName()); }
方式二:利用类名获取类--------------不推荐(需要对象的包,依赖性太强)
public static void main(String[] args) { Class<?> c = Person.class; System.out.println(c.getName()); }
方式三:利用类的全路径名获取-------------------推荐
本文主要就是讲述方式三,通过类的全路径名去获取并操作类中的方法,字段等:
实体类代码如下:
----本文中主要就是通过反射获取并操作这个实体类中的字段和方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.xnrd.common.base; public class Person { public String height; public Double weight; private int age; public Person() { super(); } public Person(int age) { super(); this.age = age; } public Person(Double weight, int age) { super(); this.weight = weight; this.age = age; } private Person(String height, int age) { super(); this.height = height; this.weight = weight; this.age = age; } public Person(String height, Double weight, int age) { super(); this.height = height; this.weight = weight; this.age = age; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //自定义几个方法 public void methodOne(String str) { System.out.println("您吃饭了吗?"); } private void methodTwo() { System.out.println("我吃了?"); } String methodThree(String height, Double weight,int age) { System.out.println("我是第三个方法!"); return height+ weight+ age; } protected void methodFour() { System.out.println("我是第四个方法!"); } public static void main(String[] args) { System.out.println("Person的main方法执行成功!"); } }
一、反射获取构造方法
public static void getConstructors() { try { Class<?> class1 = Class.forName("com.xnrd.common.base.Person"); //获取类名 System.out.println(class1.getName()); System.out.println("------------------所有公用的构造方法---------------------------------"); //获取所有公用的构造方法 Constructor<?>[] constructors = class1.getConstructors(); for(Constructor<?> c : constructors) { System.out.println(c); } System.out.println("-------------------所有的构造方法(包括私有的)--------------------------------"); //获取所有的构造方法(包括私有的) Constructor<?>[] declaredconstructors = class1.getDeclaredConstructors(); for(Constructor<?> c : declaredconstructors) { System.out.println(c); } System.out.println("-------------------公有的有参构造方法--------------------------------"); //获取公有的有参构造方法 Constructor<?> declaredcons1 = class1.getConstructor(new Class[] {Double.class,int.class}); System.out.println(declaredcons1); System.out.println("-------------------私有的有参构造--------------------------------"); //获取私有的有参构造 Constructor<?> declaredconstructor1 = class1.getDeclaredConstructor(new Class[] {String.class,int.class}); System.out.println(declaredconstructor1); } catch (Exception e) { e.printStackTrace(); } }
执行结果:
com.xnrd.common.base.Person
------------------所有公用的构造方法---------------------------------
public com.xnrd.common.base.Person(java.lang.String,java.lang.Double,int)
public com.xnrd.common.base.Person(java.lang.Double,int)
public com.xnrd.common.base.Person(int)
public com.xnrd.common.base.Person()
-------------------所有的构造方法(包括私有的)--------------------------------
public com.xnrd.common.base.Person(java.lang.String,java.lang.Double,int)
private com.xnrd.common.base.Person(java.lang.String,int)
public com.xnrd.common.base.Person(java.lang.Double,int)
public com.xnrd.common.base.Person(int)
public com.xnrd.common.base.Person()
-------------------公有的有参构造方法--------------------------------
public com.xnrd.common.base.Person(java.lang.Double,int)
-------------------私有的有参构造--------------------------------
private com.xnrd.common.base.Person(java.lang.String,int)
二、反射获取字段并使用
public static void getFilds() { try { Class<?> class1 = Class.forName("com.xnrd.common.base.Person"); System.out.println("-------------------所有公有字段--------------------------------"); //获取所有公有字段 Field[] fildFields = class1.getFields(); for(Field field : fildFields) { System.out.println(field); } System.out.println("-------------------所有字段(包括私有)--------------------------------"); //获取所有字段(包括私有) Field[] fields = class1.getDeclaredFields(); for(Field field : fields) { System.out.println(field); } //获取指定的字段 Field field = class1.getField("height"); //获取一个公有的无参构造,然后实例化,并给字段赋值 Object object = class1.getConstructor().newInstance(); field.set(object, "166"); System.out.println("-------------------测试字段设置是否成功--------------------------------"); //测试是否设置成功 Person person = (Person)object; System.out.println(person.getHeight()); System.out.println("-------------------获取私有字段并使用--------------------------------"); Field field2 = class1.getDeclaredField("age"); field2.setAccessible(true); //暴力反射 获取私有字段必须添加此行 field2.set(object, 25); System.out.println(person.getAge()); } catch (Exception e) { e.printStackTrace(); } }
执行结果:
-------------------所有公有字段--------------------------------
public java.lang.String com.xnrd.common.base.Person.height
public java.lang.Double com.xnrd.common.base.Person.weight
-------------------所有字段(包括私有)--------------------------------
public java.lang.String com.xnrd.common.base.Person.height
public java.lang.Double com.xnrd.common.base.Person.weight
private int com.xnrd.common.base.Person.age
-------------------测试字段设置是否成功--------------------------------
166
-------------------获取私有字段并使用--------------------------------
25
三、反射获取方法并调用方法
public static void getMethod() { try { Class<?> class1 = Class.forName("com.xnrd.common.base.Person"); System.out.println("-------------------获取类中公有的方法--------------------------------"); //获取所有public 修饰的方法 Method[] methods = class1.getMethods(); for(Method method : methods) { System.out.println(method); } System.out.println("-------------------获取类中的所有方法--------------------------------"); //获取所有的方法(包括私有的) Method[] methods2 = class1.getDeclaredMethods(); for(Method method : methods2) { System.out.println(method); } System.out.println("-------------------获取类中的指定方法并使用--------------------------------"); Method method = class1.getMethod("methodOne", String.class); System.out.println(method); System.out.println("-------------------获取类中指定的不带参数的方法并使用--------------------------------"); Method method2 = class1.getDeclaredMethod("methodTwo"); System.out.println(method2); System.out.println("-------------------获取类中指定的带多个参数的方法并使用--------------------------------"); //若methodThree方法前修饰符是public 则用getMethod Method method3 = class1.getDeclaredMethod("methodThree", String.class,Double.class,int.class); System.out.println(method3); //实例化对象,验证方法是否获取成功 Object object = class1.getConstructor().newInstance(); //调用方法 Object invObject = method3.invoke(object, "166",3.14,25); System.out.println(invObject); } catch (Exception e) { e.printStackTrace(); } }
执行结果:
-------------------获取类中公有的方法--------------------------------
public static void com.xnrd.common.base.Person.main(java.lang.String[])
public int com.xnrd.common.base.Person.getAge()
public java.lang.String com.xnrd.common.base.Person.getHeight()
public void com.xnrd.common.base.Person.setHeight(java.lang.String)
public void com.xnrd.common.base.Person.setWeight(java.lang.Double)
public java.lang.Double com.xnrd.common.base.Person.getWeight()
public void com.xnrd.common.base.Person.setAge(int)
public void com.xnrd.common.base.Person.methodOne(java.lang.String)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
-------------------获取类中的所有方法--------------------------------
public static void com.xnrd.common.base.Person.main(java.lang.String[])
public int com.xnrd.common.base.Person.getAge()
public java.lang.String com.xnrd.common.base.Person.getHeight()
public void com.xnrd.common.base.Person.setHeight(java.lang.String)
protected void com.xnrd.common.base.Person.methodFour()
public void com.xnrd.common.base.Person.setWeight(java.lang.Double)
java.lang.String com.xnrd.common.base.Person.methodThree(java.lang.String,java.lang.Double,int)
public java.lang.Double com.xnrd.common.base.Person.getWeight()
private void com.xnrd.common.base.Person.methodTwo()
public void com.xnrd.common.base.Person.setAge(int)
public void com.xnrd.common.base.Person.methodOne(java.lang.String)
-------------------获取类中的指定方法并使用--------------------------------
public void com.xnrd.common.base.Person.methodOne(java.lang.String)
-------------------获取类中指定的不带参数的方法并使用--------------------------------
private void com.xnrd.common.base.Person.methodTwo()
-------------------获取类中指定的带多个参数的方法并使用--------------------------------
java.lang.String com.xnrd.common.base.Person.methodThree(java.lang.String,java.lang.Double,int)
我是第三个方法!
1663.1425
四、反射调用main方法
public static void getMainMethod() { try { Class<?> class1 = Class.forName("com.xnrd.common.base.Person"); System.out.println("------------------调用main方法---------------------------------"); Method method = class1.getMethod("main", String[].class); method.invoke(null, (Object) new String[] {"a"}); } catch (Exception e) { e.printStackTrace(); } }
执行结果:
------------------调用main方法---------------------------------
Person的main方法执行成功!