| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> Java反射机制入门 -> 正文阅读 |
|
[Java知识库]Java反射机制入门 |
1.反射机制介绍 1.1编译期是指把源码交给编译器编译成计算机可以执行的文件的过程。在 Java 中也就是把 Java 代码编成 class 文件的过程。编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本进行操作,比如检查错误。 1.2运行期是,直把编译后的文件交给计算机执行到程序运行结束。所谓运行期就把在磁盘中的代码放到内存中执行起来。 1.3Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。(简单来说,反射机制指的是程序在运行时能够获取自身的信息。在 Java 中,只要给定类的名字,就可以通过反射机制来获得类的所有信息。) 1.1.4Java 反射机制主要提供了以下功能,这些功能都位于java.lang.reflect包
1.1.5如果要想知道一个类的属性和方法,必须先获取到该类的字节码文件对象。获取类的信息时,使用的就是 Class 类中的方法。所以先要获取到每一个字节码文件(.class)对应的 Class 类型的对象.众所周知,所有 Java 类均继承了 Object 类,在 Object 类中定义了一个 getClass() 方法,该方法返回同一个类型为 Class 的对象。例如,下面的示例代码: //方式1 还未装载到内存,获取信息依然是父类对象信息 Class<? extends Class> c = Student.class.getClass(); //方式2 获取类的Class Student stu = new Student(); Class<? extends Student> stu_class = stu.getClass(); //方式3 获取类的Class Class<?> c1 = Class.forName("com.qst.test.Student"); 1.6利用 Class 类的对象 stu可以访问 Student对象的描述信息、Student类的信息以及基类 Object 的信息 2.1反射机制的优缺点 优点:
缺点:
Java 反射机制在一般的 Java 应用开发中很少使用,即便是 Java EE 阶段也很少使用,但所有的框架底层确大量的使用。 2.2反射机制API 实现 Java 反射机制的类都位于 java.lang.reflect 包中,java.lang.Class 类是 Java 反射机制 API 中的核心类。 2.3java.lang.Class类 java.lang.Class 类是实现反射的关键所在,Class 类的一个实例表示 Java 的一种数据类型,包括类、接口、枚举、注解、数组、基本数据类型和 void。Class 没有公有的构造方法,Class 实例是由 JVM 在类加载时自动创建的。 2.4java.lang.reflect java.lang.reflect包提供了反射中用到类,主要的类说明如下:
3.通过反射访问构造方法 一般情况我们可以通过反射获取构造信息,并且可以通过反射实例化对象 方法:
案例使用类 package com.qst.reflectsss; public class Apple { ? ? private String color; ? ? public int price; ? ? public Apple() { ? ? } ? ? private Apple(String color) { ? ? ? ? this.color = color; ? ? } ? ? private Apple(int price) { ? ? ? ? this.price = price; ? ? } ? ? public Apple(String color, int price) { ? ? ? ? this.color = color; ? ? ? ? this.price = price; ? ? } ? ? //将number对象转换成一个字符串,并返回结果 ? ? ? ? return "Apple{" + ? ? ? ? ? ? ? ? "color='" + color + '\'' + ? ? ? ? ? ? ? ? ", price=" + price + ? ? ? ? ? ? ? ? '}'; ? ? } } 案例测试代码 package com.qst.reflectsss; import java.lang.reflect.Constructor; public class AppleTest { ? ? public static void main(String[] args) throws Exception { ? ? ? ? //读取字节码类 ? ? ? ? //读取构造方法 - 只获取公开的构造 ? ? ? ? for (Constructor cr:constructors) { ? ? ? ? ? ? System.out.println("获取公开的构造:"+cr); ? ? ? ? } ? ? ? ? System.out.println("============================================"); ? ? ? ? //获取所有的构造 ? ? ? ? for (Constructor cr:declaredConstructors) { ? ? ? ? ? ? System.out.println("获取所有的构造:"+cr); ? ? ? ? } ? ? ? ?? ? ? ? ? System.out.println("============================================="); ? ? ? ? //获取空的 ? ? ? ? System.out.println("获取空构造:"+constructor); ? ? ? ? System.out.println("============================================="); ? ? ? ? //获取有参的 ? ? ? ? System.out.println("获取有参构造:"+constructor1); ? ? ? ? System.out.println("============================================="); ? ? ? ? //测试使用getConstructor获取私有的构造 ? -- ?不可以 ? ? ? ? System.out.println("获取私有构造:"+constructor3); ? ? ? ? System.out.println("============================================="); ? ? ? ? //实例化对象 ?== ?公开的空构造 ? ? ? ? Apple app = (Apple)constructor4.newInstance(); ? ? ? ? System.out.println("获取公开构造:"+app);//输出内存地址 ? ? ? ? //实例化对象 ?== ?公开的有参构造); ? ? ? ? Apple app1 = (Apple)constructor5.newInstance("红富士",5); ? ? ? ? System.out.println("获取公开的有参构造:"+app1); ? ? ? ? System.out.println("============================================="); ? ? ? ? //实例化对象 ?== ?私有的有参构造 ? ? ? ? //暴力反射 ?== ?授权允许操作私有的 ? ? ? ? Apple app2 = (Apple)constructor6.newInstance("红富士"); ? ? ? ? System.out.println("获取私有的有参构造:"+app2); ? ? } } 4.通过反射访问方法 方法:
案例使用类 package com.qst.reflectsss; /* ? ? public Cat() { ? ? } ? ? //测试方法 ? ? ? ? System.out.println("猫吃鱼"); ? ? } ? ? void run(){ ? ? ? ? System.out.println("猫在奔跑"); ? ? } ? ? protected String sleep(){ ? ? ? ? return "猫爱睡觉"; ? ? } ? ? private String ww(){ ? ? ? ? return "ww"; ? ? } } 案例测试代码 package com.qst.reflectsss; import java.lang.reflect.Method; public class CatTest { ? ? public static void main(String[] args) throws Exception { ? ? ? ? //字节码类 ? ? ? ? //创建对象:获取方法时用不上,但执行方法的时候一定用得上 ? ? ? ? //读取公开的方法 ?-- ?可以读取父类的公开方法 ? ? ? ? for (Method m: methods) { ? ? ? ? ? ? System.out.println("读取公开的方法:"+m); ? ? ? ? } ? ? ? ? System.out.println("===================================="); ? ? ? ? //读取所有方法 ?-- ?只能读取本类所有方法 ? ? ? ? for (Method m:declaredMethods) { ? ? ? ? ? ? System.out.println("读取所有方法:"+m); ? ? ? ? } ? ? ? ? System.out.println("===================================="); ? ? ? ? //读取单个方法 -- 读取公开的 ? ? ? ? System.out.println("读取eat方法:"+eat); ? ? ? ? System.out.println("===================================="); ? ? ? ? //读取不公开的方法 ? ? ? ? Method sleep = c.getDeclaredMethod("sleep"); ? ? ? ? Method ww = c.getDeclaredMethod("ww"); ? ? ? ? System.out.println("读取不公开方法:"+run); ? ? ? ? System.out.println("读取不公开方法:"+sleep); ? ? ? ? System.out.println("读取不公开方法:"+ww); ? ? ? ? System.out.println("=================测试方法执行=============="); ? ? ? ? //测试无返回值,公开的 ? ? ? ? System.out.println("测试公开无返回值的:"+invoke); ? ? ? ? //测试有返回值,且不公开的 ? ? ? ? System.out.println("测试不公开有返回值的:"+invoke1); ? ? ? ? //私有的方法,一定需要设置反射权限,暴力反射 ? ? ? ? Object invoke2 = ww.invoke(cat); ? ? ? ? System.out.println("测试不公开有返回值的:"+invoke2); ? ? ? ? Object invoke3 = run.invoke(cat); ? ? ? ? System.out.println("测试不公开有返回值的:"+invoke3); ? ? } } 5.通过反射访问属性 方法:
案例使用类 package com.qst.reflectsss; public class Dog { ? ? public String name; ? ? int age; ? ? public String color; ? ? public String eat; ? ? public Dog() { ? ? } ? ? 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 String getColor() { ? ? ? ? return color; ? ? } ? ? public void setColor(String color) { ? ? ? ? this.color = color; ? ? } ? ? public String getEat() { ? ? ? ? return eat; ? ? } ? ? public void setEat(String eat) { ? ? ? ? this.eat = eat; ? ? } ? ? @Override ? ? ? ? return "Dog{" + ? ? ? ? ? ? ? ? "name='" + name + '\'' + ? ? ? ? ? ? ? ? ", age=" + age + ? ? ? ? ? ? ? ? ", color='" + color + '\'' + ? ? ? ? ? ? ? ? ", eat='" + eat + '\'' + ? ? ? ? ? ? ? ? '}'; ? ? } } 案例测试代码 package com.qst.reflectsss; import java.lang.reflect.Field; public class DogTest { ? ? public static void main(String[] args) throws Exception { ? ? ? ? Class<?> c = Class.forName("com.qst.reflectsss.Dog"); ? ? ? ? Dog dog = (Dog)c.newInstance(); ? ? ? ? //获取公开的属性信息 ? ? ? ? for (Field f :fields) { ? ? ? ? ? ? System.out.println("获取公开的属性信息:"+f); ? ? ? ? } ? ? ? ? System.out.println("===================================="); ? ? ? ? //获取所有的属性信息 ? ? ? ? for (Field f:declaredFields) { ? ? ? ? ? ? System.out.println("获取所有的属性信息:"+f); ? ? ? ? } ? ? ? ? System.out.println("===================================="); ? ? ? ? //获取单个的属性信息 ? ? ? ? System.out.println("获取单个的属性信息:"+name); ? ? ? ? System.out.println("===================================="); ? ? ? ? //获取单个非公开的属性 ? ? ? ? System.out.println("获取单个非公开的属性:"+age); ? ? ? ? Field eat = c.getDeclaredField("eat"); ? ? ? ? System.out.println("获取单个非公开的属性"+eat); ? ? ? ? System.out.println("===================================="); ? ? ? ? //取值与赋值 ? ? ? ?/* dog.setName("来福"); ? ? ? ? dog.setColor("大黄"); ? ? ? ? eat.set(dog,"啃骨头"); ? ? ? ? System.out.println("查看赋值操作:"+dog); ? ? ? ? Object o = name.get(dog); ? ? ? ? System.out.println("通过反射取值:"+o); ? ? } } 6.newInstance()和new()区别 1、两者创建对象的方式不同,前者是实用类的加载机制,后者则是直接创建一个类: 2、newInstance创建类是这个类必须已经加载过且已经连接,new创建类是则不需要这个类加载过 3、newInstance: 弱类型(GC是回收对象的限制条件很低,容易被回收)、低效率、只能调用无参构造,new 强类型(GC不会自动回收,只有所有的指向对象的引用被移除是才会被回收,若对象生命周期已经结束,但引用没有被移除,经常会出现内存溢出) ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/29 7:46:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |