Java 反射
1、类的生命周期
参考资料:https://www.cnblogs.com/jhxxb/p/10900405.html
2、类加载器
2.1、类加载器的分类
-
启动类加载器
-
扩展类加载器
-
系统类加载器
参考资料:https://blog.csdn.net/m0_38075425/article/details/81627349
public static void main(String[] args) {
System.out.println("person类是哪种类型的类加载器加载="+Person.class.getClassLoader());
//获取启动类加载器的加载路径
URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
//遍历路径数组并输出
for(URL url:urls) {
System.out.println(url.toExternalForm());
}
System.out.println("获取扩展类加载器加载的路径");
//获取扩展类加载器
ClassLoader extClassLoader=Student.class.getClassLoader().getParent();
//获取扩展类加载器加载的路径
URL[] urls2= ((URLClassLoader)extClassLoader).getURLs();
//遍历路径数组并输出
for(URL url:urls2) {
System.out.println(url.toExternalForm());
}
System.out.println("获取用户系统的类加载器加载的路径");
//获取系统类加载器路径
URL urls3[]= ((URLClassLoader)Student.class.getClassLoader()).getURLs();
//遍历路径数组并输出
for(URL url:urls3) {
System.out.println(url.toExternalForm());
}
}
3、反射机制
它允许运行中的Java程序获取自身的信息,并且可以操作类或对象的内部属性。
3.1、反射机制起作用的原因
通过类加载器将类加载到内存,它就会生成一个Class类对象 ,此对象可以访问类的静态存储结 构,因此就可以使到在运行期间(runtime) ,可以动态操作类或者对象内部属性及方法。
3.2、获取Class对象
下面代码展示的前提是有一个People类
package reflect;
public class People {
public String name;//姓名
private int age;//年龄
public static double height;//身高
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show(){
System.out.println("hello");
}
public void show(String s){
System.out.println(s);
}
private void show(int i){
System.out.println(i);
}
获取Class对象通常有三种方式
-
Object ——> getClass();
-
任何数据类型(包括基本数据类型)都有一个“静态”的class属性
-
通过Class类的静态方法:forName(String className)(常用)
public static void main(String[] args) throws ClassNotFoundException {
People people=new People();
//获取Class方式一
Class peopleClass1=people.getClass();
System.out.println(peopleClass1);
//获取Class方式二
Class peopleClasss2=Class.forName("reflect.People");
System.out.println(peopleClasss2);
//获取Class方式三
Class peopleClass3=People.class;
System.out.println(peopleClass3);
}
3.3、通过反射创建对象
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//创建People对象
People people=peopleClasss.newInstance();
}
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//获取People的有参构造器
Constructor<People> constructor=peopleClasss.getConstructor(String.class,int.class);
//通过有参构造器创建People对象
People people=constructor.newInstance("yl",18);
System.out.println(people);
}
3.5、通过反射操作非静态属性
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//创建People对象
People people=peopleClasss.newInstance();
//通过Class获取name属性
Field nameField=peopleClasss.getField("name");
//设置属性值
nameField.set(people,"lsy");
//获取属性值
String name=(String) nameField.get(people);
System.out.println(name);
}
3.6、通过反射操作静态属性
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//通过Class获取name属性
Field nameField=peopleClasss.getField("height");
//设置属性
nameField.set(null,50.1);
//获取属性值
double name=(double) nameField.get(peopleClasss);
System.out.println(name);
}
3.7、通过反射调用无参方法
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//创建People对象
People people=peopleClasss.newInstance();
//获取方法
Method showMethod=peopleClasss.getMethod("show");
//执行方法
showMethod.invoke(people);
}
3.8、通过反射调用有参方法
public static void main(String[] args) throws Exception {
//获取Class
Class<People> peopleClasss=(Class<People>) Class.forName("reflect.People");
//创建People对象
People people=peopleClasss.newInstance();
//获取方法
Method showMethod=peopleClasss.getMethod("show",String.class);
//执行方法
showMethod.invoke(people,"hello");
}
3.9、通过反射访问私有属性
public static void main(String[] args) throws Exception {
//获取Class
Class peopleClasss=Class.forName("com.yl.reflect.People");
//创建People对象
People people=(People) peopleClasss.newInstance();
//获取age属性
Field ageField=peopleClasss.getDeclaredField("age");
//抑制访问检查
ageField.setAccessible(true);
//设置age属性值
ageField.set(people,18);
System.out.println(people);
}
3.10、通过反射访问私有方法
public static void main(String[] args) throws Exception {
//获取Class
Class peopleClasss=Class.forName("com.yl.reflect.People");
//创建People对象
People people=(People) peopleClasss.newInstance();
//获取私有show方法
Method showMethod=peopleClasss.getDeclaredMethod("show",int.class);
//抑制访问检查
showMethod.setAccessible(true);
//执行showMethod
showMethod.invoke(people,7);
}
3.11、通过反射操作数组
public static void main(String[] args) throws Exception {
//通过反射创建数组
int[] ints= (int[]) Array.newInstance(int.class,3);
//给数组赋值
Array.set(ints,0,100);
Array.set(ints,1,200);
Array.set(ints,2,300);
//获取数组的值并输出
System.out.println(Array.get(ints,0));
System.out.println(Array.get(ints,1));
System.out.println(Array.get(ints,2));
}
记得快乐
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!