java的反射机制
2022/2/26 11:51:27
本文主要是介绍java的反射机制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一.什么是反射
反射是java中的动态机制,它允许我们在程序运行期间再确定对象的实例化,方法的调用, 属性的操作等。使得程序的灵活度大大提升,但是同时也带来了更多的资源开销和较低的 运行效率。 程序不能过度的依赖反射机制。
2.反射获取方式
Class 类对象 Class的每一个实例用于表示JVM中加载的一个类,并且每个被JVM加载的类都 有且只有一个Class的实例。 通过Class我们可以得知其表示的类的一切信息:类名,包名,有哪些构造器,方法 属性等。并在运行期间获取后进行相关操作。 因此反射操作的第一步就是获取要操作的类的类对象。 获取一个类的类对象方式有: 1: 类名.class 例如: Class cls = String.class; Class cls = int.class; 注:基本类型只能通过上述方式获取类对象2: Class.forName(String className) 使用Class的静态方法forName传入要加载的类的完全限定名(包名.类名) 例如: Class cls = Class.forName("java.lang.String")3:类加载器ClassLoader形式
3.常用方法
Class cls = Class.forName("reflect.Person"); //通过类对象获取其表示的String的相关信息 String name = cls.getName(); //获取包名和类名 name = cls.getSimpleName(); //获取类名 System.out.println(cls.getPackage().getName()); //获取包名 //类对象提供了方法newInstance()可以调用无参且公开的构造器实例化 Object o = cls.newInstance(); 2获取对应的构造器 Person(String name,int age) // cls.getConstructor();//不传参获取的为无参构造器 //3通过构造器实例化对象 new Person("王五",22); Object o = cls.newInstance("王五",22); //获取当前类对象所表示的类的所有公开方法(包含从超类继承的方法) Method[] methods = cls.getMethods(); //获取私有方法 Method method = cls.getDeclaredMethod("secret"); //强行打开访问权限 method.setAccessible(true);
利用反射机制调用方法: invoke
1.调用无参方法
public class ReflectDemo4 { public static void main(String[] args) throws Exception { Person p = new Person(); p.sayHello(); Scanner scanner = new Scanner(System.in); System.out.println("请输入类名:"); String className = scanner.nextLine(); System.out.println("请输入方法名:"); String methodName = scanner.nextLine(); //实例化 // Class cls = Class.forName("reflect.Person"); Class cls = Class.forName(className); Object o = cls.newInstance();//Person o = new Person(); //获取要调用的方法 //仅传入方法名时,是获取该无参方法 // Method method = cls.getMethod("sayHello");//表示的Person的成员方法sayHello() Method method = cls.getMethod(methodName); method.invoke(o);//o.sayHello() } }
2. 调用有参方法
public class ReflectDemo5 { public static void main(String[] args) throws Exception { Class cls = Class.forName("reflect.Person"); Object o = cls.newInstance(); Method method = cls.getMethod("dosome",String.class);//dosome(String) method.invoke(o,"玩游戏");//p.dosome("玩游戏"); Method method1 = cls.getMethod("dosome",String.class,int.class); method1.invoke(o,"看电视",5); } }
4.反射中使用的注解
定义@AutoRunClass 注解
该注解是用来标注那些可以被反射机制自动调用的类
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AutoRunClass { }
定义注解时,我们通常会使用java内置的两个注解来加以修饰 1.@Retention 用来指定当前注解的保留级别。有三个可选值, 对应: RetentionPolicy.SOURCE 表示当前注解仅保留在源码中 RetentionPolicy.CLASS(默认值) 表示注解会保留在字节码中,但是反射机制不可用 RetentionPolicy.RUNTIME 表示保留在字节码文件中,但是可以被反射机制使用 通常我们定义的注解都会指定为RUNTIME级别,辅助反射机制的操作。2.@Target用于表示当前注解可以在什么位置上使用。可选项都定义在ElementType上 常见的有: ElementType.TYPE 在类上使用 ElementType.FIELD 在属性使用 ElementType.METHOD 在方法上使用 ...
判断是否被注解标注 : isAnnotationPresent(注解名.class)
public class ReflectDemo7 { public static void main(String[] args) throws Exception { //判断一个类是否有被@AutoRunClass标注 // Class cls = Class.forName("reflect.Person"); // Class cls = Class.forName("reflect.Student"); Class cls = Class.forName("reflect.Test2"); /* 出了Class之外,像Method,Filed等其他反射对象也支持isAnnotationPresent 方法,用来表示是否被指定注解标注。 比如: Method的这个方法就是判断其表示的方法是否有被指定注解标注。 Constructor的这个方法就是判断其表示的构造器是否被指定注解标注。 */ if(cls.isAnnotationPresent(AutoRunClass.class)){ System.out.println(cls.getName()+":被@AutoRunClass标注了!"); }else{ System.out.println(cls.getName()+":没有被@AutoRunClass标注了!"); } } }
这篇关于java的反射机制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)