java反射学习
反射概述:
反射可以帮助我们在动态运行的时候,对于任意一个类,可以获得其所有方法,所有的变量(是所有的!包括私有!)
Class类:
Java中java.lang.Class类用于表示一个类的字节码(.class)文件
如何得到某个class文件对应的Class对象
已知类和对象的情况下
类名.class
对象.getClass() — Object 类提供
未知类和对象的情况下
Class.forName(“包名.类名”)
写一个Animal类:
package org.example;
public class Animal {
public String name;
private int id;
public Animal(){
System.out.println("我是无参构造方法");
}
public Animal(int id,String name){
this.setId(id);
this.setName(name);
System.out.println("我是有参构造方法");
}
public void eat(){
System.out.println("我是公有方法");
}
private void drink(){
System.out.println("我是私有方法");
}
private void play(String name,String sex){
System.out.println("我是私有带参方法");
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
然后写一个获取Class对象的反射调用的类
package org.example;
public class Classtest {
public void demo() throws ClassNotFoundException{
Class class1 = Animal.class; //1.通过类名.class的方式
Animal animal =new Animal();
Class class2 = animal.getClass(); //2.通过对象.getClass()的方式
Class class3 = Class.forName("org.example.Animal"); //3.Class类forName();获得
}
public static void main(String[] args) throws ClassNotFoundException {
}
}
Constructor类:
Constructor类的实例对象代表类的一个构造方法
得到某个类所有的构造方法
Constructor [] constructors = Class.forName(“java.lang.String”).getConstructors();
得到指定的构造方法并调用
Constructor constructor = Class.forName(“java.lang.String”).getConstructors(String.class);
String str = (String)constructor.newInstance(“abc”);
Class类的newInstance()方法用来调用类的默认构造方法
String obj = (String)Class.forName(“java.lang.String”).newInstance();
写一个通过反射进行调用方法的类
package org.example;
import java.lang.reflect.Constructor;
public class ConstructorTest {
public void demo1() throws Exception{
Class class1 = Class.forName("org.example.Animal");
Constructor c = class1.getConstructor();
Animal animal = (Animal) c.newInstance();
}/**
demo1是通过反射获取无参构造方法
**/
public void demo2() throws Exception{
Class class1 = Class.forName("org.example.Animal");
Constructor c = class1.getConstructor(int.class,String.class);
Animal animal = (Animal) c.newInstance(2,"猴子");
System.out.println(animal.toString());
}
/**
demo2是通过反射获得有参构造方法
**/
public static void main(String[] args) throws Exception{
ConstructorTest c =new ConstructorTest();
c.demo1();
System.out.println("-----------------------------");
c.demo2();
}
}
运行的结果:
再后面我们再新建立一个demo3函数,作用:获取所有的构造方法
代码如下:
package org.example;
import java.lang.reflect.Constructor;
public class ConstructorTest {
public void demo1() throws Exception{
Class class1 = Class.forName("org.example.Animal");
Constructor c = class1.getConstructor();
Animal animal = (Animal) c.newInstance();
}/**
demo1是通过反射获取无参构造方法
**/
public void demo2() throws Exception{
Class class1 = Class.forName("org.example.Animal");
Constructor c = class1.getConstructor(int.class,String.class);
Animal animal = (Animal) c.newInstance(2,"猴子");
System.out.println(animal.toString());
}
/**
demo2是通过反射获得有参构造方法
**/
public void demo3() throws Exception{
Class class1 = Class.forName("org.example.Animal");
Constructor[] c = class1.getConstructors();
for (Constructor constructor : c){
System.out.println("Constructor"+constructor);
}
}
/**
demo3是通过反射获取所有的构造方法
**/
public static void main(String[] args) throws Exception{
ConstructorTest c =new ConstructorTest();
c.demo1();
System.out.println("-----------------------------");
c.demo2();
System.out.println("-----------------------------");
c.demo3();
}
}
打印结果:
可以看到获取了Animal类中的所有的构造方法
Field类:
Field类代表某个类中的一个成员变量,并提供动态的访问权限
Field对象的获得
Field[] fields = c.getFields();//取得所有public属性(包括父类继承)
Field[] fields = c.getDeclaredFields();//取得所有声明的属性
得到指定的成员变量
Field name = c.getField(“name”);
Field name = c.getDeclaredField(“name”);
设置Filed变量是否可以访问
field.setAccessible(boolean);
-Field变量值的读取,设置
field.get(obj);
filed.set(obj,value);
创建一个FieldTest类
package org.example;
import java.lang.reflect.Field;
public class FieldTest {
//测试共有方法:
public void demo1() throws Exception{
Class class1 = Class.forName("org.example.Animal"); //首先获取class类
Field field = class1.getField("name"); //获取属性
/**
以下俩个行代码是进行操作属性:
**/
Animal animal = (Animal) class1.getConstructor().newInstance(); //获取Animal无参构造方法
field.set(animal,"老虎"); //将Animal.name="老虎";
//获取属性:
Object obj= field.get(animal);
System.out.println(obj);
System.out.println(animal); //会自动调用toString()方法;
}
//测试私有方法
public void demo2() throws Exception{
//获得Class:
Class class1 = Class.forName("org.example.Animal");
//获得私有属性:
Field field = class1.getDeclaredField("id");
//操作属性:
Animal animal = (Animal) class1.getConstructor().newInstance(); //获取Animal无参构造
field.setAccessible(true); //私有属性,需要设置一个可访问的权限
field.set(animal,2);
//获取值:
Object obj = field.get(animal);
System.out.println(obj);
System.out.println(animal);
}
public static void main(String[] args) throws Exception{
FieldTest fieldTest = new FieldTest();
fieldTest.demo1();
System.out.println("-----------------------------------");
fieldTest.demo2();
}
}
打印结果:
Method类:
Method类代表某个类中的一个成员方法
Method对象的获得
获得所有方法
getDeclaredMethods()
getMethods()
-获得指定的方法
getDeclaredMethod(String name,Class…parameterTypes)
getMethod(String name,Class…parameterTypes)
通过反射执行方法
invoke(Object obj,Object…args)
创建一个MethodTest类
package org.example;
import java.lang.reflect.Method;
public class MethodTest {
public void demo1() throws Exception{
//获取Class对象:
Class class1 = Class.forName("org.example.Animal");
//实例化:
Animal animal = (Animal) class1.getConstructor().newInstance();
//获得公有方法
Method method = class1.getMethod("eat");
//执行方法
method.invoke(animal); //相当于animal.eat();
}
public void demo2() throws Exception{
//获取class对象
Class class1 = Class.forName("org.example.Animal");
//实例化
Animal animal = (Animal) class1.newInstance();
//获取私有方法
Method method = class1.getDeclaredMethod("drink"); //私有方法,使用getDeclaredMethod
//设置私有的访问权限
method.setAccessible(true);
//执行该方法
method.invoke(animal); //相当于animal.drink();
}
public void demo3() throws Exception{
//获取Class对象
Class class1 = Class.forName("org.example.Animal");
//实例化
Animal animal = (Animal) class1.newInstance();
//获取私有带参方法
Method method = class1.getDeclaredMethod("play", int.class, String.class);
//设置私有访问权限
method.setAccessible(true);
//执行方法
Object obj = method.invoke(animal,2,"孔雀");
System.out.println(obj);
}
public static void main(String[] args) throws Exception{
MethodTest methodTest = new MethodTest();
methodTest.demo1();
System.out.println("--------------------------");
methodTest.demo2();
System.out.println("--------------------------");
methodTest.demo3();
}
}
运行结果:
总结:
对于Constructor类、Field类、Method类首先需要获得Class对象,然后进行newInstance实例化。