慕课网 反射

本文深入探讨Java反射机制的使用方法,包括类的获取、方法的获取与调用、成员变量的获取与操作,以及如何通过反射了解集合泛型的本质。通过具体代码示例,详细解析了反射在Java开发中的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class类的使用

Foo.java
//类是对象,类是java.lang.Class类的实例对象。
//任何一个类都是Class的实例对象,这个实例对象有三种表示方式
public class Foo {
public static void  main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
	Foo f1=new Foo();
	//第一种表示方式--->实际在告诉我们任何一个类都有一个隐含的静态成员变量class
	Class c1=Foo.class;
	//第二种表达方式--->已经知道该类的对象通过getClassF方法
	Class c2=f1.getClass();
	//第三种表达方式
	Class c3=Class.forName("Foo");
	//我们完全可以通过类的类类型创建类的对象实例--->通过c1 or c2 or c3创建Foo的实例对象
	Foo f2=(Foo) c3.newInstance();	;//需要有无参数的构造方法
}
}


动态加载类

编译时刻加载类是静态加载类,运行时刻加载类是动态加载类!
使用new 创建对象, 是静态加载类, 在编译时刻就需要加载所有的可能用到的类
Class.forName():动态加载类,在运行时加载
import java.lang.reflect.Method;


获取方法信息

public class ClassUtil {
public static void getProParam(Object obj){
	//要获取类的信息  首先要获取类的类类型
	Class c = obj.getClass();//传递的是哪个子类的对象  c就是该子类的类类型
	//获取类的名称
	System.out.println("类的名称是:"+c.getName());
	/*
	 * Method类,方法对象
	 * 一个成员方法就是一个Method对象
	 * getMethods()方法获取的是所有的public的函数,包括父类继承而来的
	 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
	 */
	Method[] ms = c.getMethods();//c.getDeclaredMethods()
	for(int i = 0; i < ms.length;i++){
		//得到方法的返回值类型的类类型
		Class returnType = ms[i].getReturnType();
		System.out.print(returnType.getName()+" ");
		//得到方法的名称
		System.out.print(ms[i].getName()+"(");
		//获取参数类型--->得到的是参数列表的类型的类类型
		Class[] paramTypes = ms[i].getParameterTypes();
		for (Class class1 : paramTypes) {
			System.out.print(class1.getName()+",");
		}
		System.out.println(")");
	}
}


获取成员变量

public static void printFieldMessage(Object obj) {
		Class c = obj.getClass();
		/*
		 * 成员变量也是对象,	java.lang.reflect.Field
		 * Field类封装了关于成员变量的操作
		 * getFields()方法获取的是所有的public的成员变量的信息
		 * getDeclaredFields获取的是该类自己声明的成员变量的信息
		 */
		//Field[] fs=c.getFields();
		Field[] fs=c.getDeclaredFields();
		System.out.println("类成员变量");
		for (Field field : fs) {
			//成员变量的类型的类类型
			Class fieldType=field.getType();
			//变量类型  变量名称
			System.out.println(fieldType.getName()+" "+field.getName());		
		}
	}




获取构造函数

public static void printConMessage(Object obj){
		Class c = obj.getClass();
		//Constructor[] cs=c.getConstructors();
		Constructor[] cs = c.getDeclaredConstructors();
		System.out.println("构造函数");
		for(Constructor con:cs){
			System.out.print(con.getName()+"(");
			Class[] paras=con.getParameterTypes();
			for(Class p:paras){
				System.out.print(p.getName()+",");
			}
			System.out.println(")");
		}
		
	}



方法反射的基本操作

1)如何获取某个方法
方法的名称和方法的参数列表才能唯一决定某个方法
2)方法反射的操作
method.invoke(对象,参数列表)
import java.lang.reflect.Method;
public class MethodDemo1 {
	public static void main(String[] args) {
	   //要获取print(int ,int )方法  1.要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型
		A a1 = new A();
		Class c = a1.getClass();
		/*
		 * 2.获取方法 名称和参数列表来决定  
		 * getMethod获取的是public的方法
		 * getDelcaredMethod自己声明的方法
		 */
	    try {
			//Method m =  c.getMethod("print", new Class[]{int.class,int.class});
	    	Method m = c.getMethod("print", int.class,int.class);
	    	
	    	//方法的反射操作  
	    	//a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
	        //方法如果没有返回值返回null,有返回值返回具体的返回值
	    	//Object o = m.invoke(a1,new Object[]{10,20});
	    	Object o = m.invoke(a1, 10,20);
	    	System.out.println("==================");
	    	//获取方法print(String,String)
             Method m1 = c.getMethod("print",String.class,String.class);
             //用方法进行反射操作
             //a1.print("hello", "WORLD");
             o = m1.invoke(a1, "hello","WORLD");
             System.out.println("===================");
           //  Method m2 = c.getMethod("print", new Class[]{});
                Method m2 = c.getMethod("print");
               // m2.invoke(a1, new Object[]{});
                m2.invoke(a1);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}      
	}
}
class A{
	public void print(){
		System.out.println("helloworld");
	}
	public void print(int a,int b){
		System.out.println(a+b);
	}
	public void print(String a,String b){
		System.out.println(a.toUpperCase()+","+b.toLowerCase());
	}
}





通过反射了解集合泛型的本质

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class classdemo3 {
	public static void main(String[] args) {		
		ArrayList list=new ArrayList();
		ArrayList<String> list1 = new ArrayList<String>();
		list1.add("hello");
		//list1.add(1); 错误的
		//反射的操作都是编译之后的操作
		Class c = list.getClass();
		Class c1 = list1.getClass();
		System.out.println(c==c1); //true
	
		/*
		 * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
		 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效,
		 * 绕过编译就无效了
		 * 验证:我们可以通过方法的反射来操作,绕过编译
		 */
		try {
			Method m1 =c1.getMethod("add", Object.class);
			m1.invoke(list1, 100);//绕过编译操作就绕过了泛型
			System.out.println(list1);
						
		} catch (Exception e) {
		  e.printStackTrace();
		}
	}
}


### 关于笔记插件或扩展程序 对于希望增强用户体验以及功能性的笔记,可以考虑使用浏览器的扩展程序来实现特定需求。虽然官方可能并未提供专门针对笔记的插件或agent,但存在一些通用型的学习辅助工具能够帮助用户更高效地管理在线程中的笔记。 #### 浏览器扩展程序 许多现代浏览器支持安装第三方开发的扩展程序,这些扩展可以帮助改善页浏览体验并增加额外的功能。例如: - **Evernote Web Clipper** 这款流行的剪辑工具允许用户轻松保存来自任何站的内容到个人账户中,非常适合用来记录和整理上学习过程中遇到的重要知识点[^1]。 ```javascript // 使用Web Clipper保存页面片段至云端笔记本服务 evernote.webClipper.savePageSelection(); ``` - **Notion Web Clipper** 类似地,Notion也提供了强大的络剪藏功能,除了基本的文字图片外还能链接整个页结构,方便日后复习查阅。 #### 自定义脚本/油猴脚本 如果现有解决方案无法满足个性化的需求,则可以通过编写自定义JavaScript代码或者利用GreaseMonkey/Tampermonkey这类用户脚本来定制化操作。这使得开发者可以根据具体场景调整交互逻辑,比如自动提取视频下方评论区精华作为补充资料加入笔记里。 ```javascript // 示例:获取当前页面所有h2标题下的文本内容用于快速生成大纲 const headings = document.querySelectorAll('h2'); let outlineText = ''; headings.forEach((heading) => { outlineText += heading.innerText + '\n'; }); console.log(outlineText); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值