写在前面的话:
- 参考资料:尚硅谷视频
- 本章内容:如何通过反射调用属性与方法【在前面文章的基础上拓展】
- IDE:eclipse
- JDK:Java8
目录
1.调用属性
1.1 调用声明为public的属性
主要分为5步骤:
- 创建Class类的实例 【点击这里,学习如何创建Class类的实例】
- 获取构造器【点击这里,学习如何获取构造器】
- 通过获取的构造器,创建对象
- 获取属性【核心,点击这里,学习如何获取属性】
- 调用获取到的属性,并通过设置来改变属性的值
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/*
* 调用属性
*/
public class TestField {
public static void main(String[] args) throws Exception {
Class<Person> clazz = Person.class;
//1.获取构造器
Constructor<Person> person = clazz.getConstructor();
//2.通过构造器创建一个对象
Person p1 = person.newInstance();
//3.获取属性
Field name = clazz.getField("name");
//4.对属性进行赋值
name.set(p1, "张三");
//5.打印输出该信息
System.out.println(p1);
}
}
效果截图:
1.2 调用非public的属性
当然通过此方法,一样也可以调用声明为public的属性。
主要改变了两个地方:
- 获取属性,应该使用getDeclaredField()方法
- 设置属性可以访问,通过setAccessible()方法
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/*
* 调用属性
*/
public class TestField {
public static void main(String[] args) throws Exception {
Class<Person> clazz = Person.class;
//1.获取构造器
Constructor<Person> person = clazz.getConstructor();
//2.通过构造器创建一个对象
Person p1 = person.newInstance();
System.out.println(p1);
//3.获取属性
Field address = clazz.getDeclaredField("address");
//4.将属性设定为可访问
address.setAccessible(true);
//4.对属性进行赋值
address.set(p1, "中国重庆");
//5.打印输出该信息
System.out.println(p1);
}
}
效果截图:
2.调用方法
2.1 调用声明为public的方法
2.1.1 方法的返回类型为void
主要分为5步骤:(与调用属性非常相似,只是有些地方略有不同)
- 创建Class类的实例 【点击这里,学习如何创建Class类的实例】
- 获取构造器【点击这里,学习如何获取构造器】
- 通过获取的构造器,创建对象
- 获取方法【核心,点击这里,学习如何获取方法】
- 调用获取到的方法,通过invoke()方法来进行调用(与调用属性不同之处)
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestMethod {
public static void main(String[] args) throws Exception{
//1.创建Class类的实例
Class<Person> clazz = Person.class;
//2.获取构造器
Constructor<Person> person = clazz.getDeclaredConstructor();
//3.创建对象
Person p1 = person.newInstance();
//4.获取方法
Method method = clazz.getMethod("show");
//5.调用方法
Object obj = method.invoke(p1);
//6.打印返回值【可有可无】
System.out.println(obj);
}
}
效果截图:
2.1.2 方法返回类型为:非void
说明:
- 如果调用的方法含有输出语句,就输出,否则调用invoke不起作用
- 调用的方法有返回值,在invoke()方法的后面进行输出返回值
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestMethod {
public static void main(String[] args) throws Exception{
//1.创建Class类的实例
Class<Person> clazz = Person.class;
//2.获取构造器
Constructor<Person> person = clazz.getDeclaredConstructor();
//3.创建对象
Person p1 = person.newInstance();
//4.获取方法
Method method = clazz.getMethod("toString");
//5.调用方法
Object obj = method.invoke(p1);//没有输出语句,控制台不显示任何信息
//6.打印返回值【必要】
System.out.println(obj);//Person [name=null, age=0, sex=null, address=null]
}
}
效果截图
2.1.3 调用静态方法
说明:
- 在invoke()方法中,参数直接填入类名(如:Person.class)
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestMethod {
public static void main(String[] args) throws Exception{
//1.创建Class类的实例
Class<Person> clazz = Person.class;
//2.获取构造器
Constructor<Person> person = clazz.getDeclaredConstructor();
//3.创建对象
Person p1 = person.newInstance();
//4.获取方法
Method method = clazz.getMethod("output");
//5.调用方法
Object obj = method.invoke(Person.class);//无需填入对象
//6.打印返回值【可有可无】
System.out.println(obj);
}
}
效果截图
2.2 调用非public的方法
说明:
与获取属性、方法相似。
- 需要使用getDeclaredMethod()方法
- 需要使用setAccessible(true),设置成可以访问
代码示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestMethod {
public static void main(String[] args) throws Exception{
//1.创建Class类的实例
Class<Person> clazz = Person.class;
//2.获取构造器
Constructor<Person> person = clazz.getDeclaredConstructor();
//3.创建对象
Person p1 = person.newInstance();
//4.获取方法
Method method = clazz.getDeclaredMethod("shadow");//私有方法
//5.设置方法可访问
method.setAccessible(true);
//5.调用方法
Object obj = method.invoke(p1);
//6.打印返回值【可有可无】
System.out.println(obj);
}
}
效果截图
3.使用构造器
构造器:一般分为有参构造器和无参构造器
3.1 无参构造器
之前很多代码,都是采用这种方式,这里简单略过
Class<Person> clazz = Person.class;
Constructor<Person> person = clazz.getDeclaredConstructor();
3.2 有参构造器
如何创建?
- 在getDeclaredConstructor()填入参数即可,如:String.class
- 通过此构造器创建对象是,newInstance()里也要填入相应的参数,如:"张三"
代码示例
import java.lang.reflect.Constructor;
public class TestConstructor {
public static void main(String[] args) throws Exception {
Class<Person> clazz = Person.class;
Constructor<Person> person = clazz.getDeclaredConstructor(String.class,int.class);//填入你要使用的构造器的参数
//创建对象
Person p1 = person.newInstance("张三",10);
System.out.println(p1);
}
}
效果截图
4.GitHub已上传代码
点击链接,可以下载代码获取代码,感受一下Java中的反射
gitee网站也上传了代码:点击链接,获取代码