Java之旅(2)—反射

 1.     概念

  反射就是将java类中的各种成分映射成相应的java类。之前我们已经讲过了Class类,也明白了一个java类中用一个Class类的对象来表示,一个类中的组成部分有:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示。

  举个生活中的例子,生活中我们经常见到汽车,如果说汽车是一个类的话,那么汽车中的发动机、变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示的,就是Field,Method,Contructor以及Package等等。 

 2.     机制及应用场合

  在运行状态中,对于任何一个类,都能够知道这个类的所以的属性和方法;对于任何一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法就是反射,java反射的动态机制是Reflection,指的就是可以用于运行期间的加载和探知,使用编译期间完全未知的classes。换言之,java程序课可以加载一个运行时才知道的class,获悉其完整构造(不包含method定义)。

  在编译时根本无法知道该对象或者类可能属于哪些类,程序只是依靠运行时的信息来发现该对象和类的真实的信息。

 3.     作用

  通过反射我们可以使程序代码访问装载到JVM中的类的内部信息,获取已装载类的属性信息、方法、构造方法的信息。

我们前面的介绍到了Class类是java反射机制的起源和入口,用户获取与类相关的各种信息,提供了获取类信息的相关的方法,Class类继承自Object类,Class类是所有类的共同的图纸。

  Class类的一些方法如下图所示:

 4.     各种反射的应用

  ? 构造方法  Constructor类

  一个类有多个构造方法,根据参数的个数和类型不用来区别,java中的构造方法是没有顺序的;利用构造方法类型的方法可以反射得到相应的类;由构造方法可以得到相应的实例对象,根据方法的反射得到这个构造方法到底是哪个类的构造方法,如下面所示:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>Constructor constructor1 = String.class
				.getConstructor(StringBuffer.class);
		String str2 = (String) constructor1
				.newInstance(new StringBuffer("abc"));</strong></span>

  只是知道是个构造方法,但是不知道是哪个构造方法,只有在运行的时候才能知道

  上例中我们看到存在两个StringBuffer,

  第一个表示用的是String众多中哪个构造方法,由上例可知,用的是参数为StringBuffer的构造方法。表示的是获得方法时要用到类型。

  第二个表示是用的时候必须传入一个stringbuffer的对象;利用构造方法的newInstance反射可以得到这个类的实例对象,创建这个类型实例对象,从而将构造方法的相同的类型参数进行传入表示调用了某个方法。调用获取的方法时要用到上面相同类型的实例对象。

  值得注意的是:参数必须是匹配的,如果不匹配,则会报错。编译的时候只是执行语法检查,并不执行等号右边的代码,只是在运行的时候才能知道其是一个String,故而下面的要加上(String)。

  Ps:除了构造方法具有newInstance()方法外,Class同样具有,也就是Class.newInstance(),比如:

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>Stringobj=(String)Class.forName(“java.lang.String”).newInstance();</strong></span>

  该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

  ? 成员变量 Filed类

  定义一个ReflectPoint类,然后在一个类中进行调用。

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>ReflectPoint pt1 = new ReflectPoint(3, 5);
		Field fieldY = pt1.getClass().getField("y");
		System.out.println(fieldY.get(pt1));
		System.out.println(fieldY);
</strong></span>

  Field fieldY = pt1.getClass().getField("y");如果你认为这个表达式得到的值是5,那就错了,fieldY不是对象身上的变量,而是类上的,要用它去取某个对象上对应的值。

  fieldY.get(pt1),上面我们知道fieldY是某个类上的变量,返回类型是个类型,也可以说是一个类,利用它的get方法可以反射得到相应的实例对象并且获取实例对象上对应的值。

  ?  成员方法的反射

  就是一个类中定义的方法,Method类代表某个类中的一个成员方法,将一个类中各个成分反射成其对应的java类就是反射。

得到类中的一个方法,利用getMethod得到的是一个Method类型的类,并且可以在括号中匹配相应的参数类型与类名。反射方式得到字节码中的方法,再拿出这个方法去作用于某个对象。

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(str1, 1));
</strong></span>

  方法的调用肯定是基于某个对象的:

   1.也就是在对象str1身上调用了定义charAt方法(methodCharAt)方法,后面的1是方法的参数

   2.利用反射的方式得到字节码中的方法,再拿出这个方法作用于某个对象。Invoke表示的是调用。

   3.也就是方法执行了调用的动作,invoke是这个方法对象身上的方法。

  故而invoke中第一个即为相应的实例对象,第二个为参数,不管参数有无,均称之为参数。

   举个简单的例子:

   画圆或者火车停车只是人发信号,操作由其本身来执行。方法是对象本身在调用,而人只是发了个通知或者信号,执行的动作只是自己的动作。人的作用就是发信号和通知而已,也就是说谁拥有数据谁就是专家,也就是对象本身。

   什么方法调用时是不需要对象?答案是静态方法。静态方法调用的时候不需要对象,所以不需要对象的肯定是静态方法。运用方法的方法反射得到某个实例对象。

<span style="font-family:Microsoft YaHei;font-size:14px;"><strong>Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println(methodCharAt.invoke(null, 1));</strong></span>

 5.      小结

  反射就是将java类中的各个成分反射成相应的类,熟悉以及掌握反射将会帮助我们更好地开发程序。学习研究仍在继续。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 23:03:57

Java之旅(2)—反射的相关文章

JAVA之旅(七)——final关键字 , 抽象类abstract,模板方法模式,接口interface,implements,特点,扩展

JAVA之旅(七)--final关键字 , 抽象类abstract,模板方法模式,接口interface,implements,特点,扩展 OK,我们继续学习JAVA,美滋滋的 一.final 我们来聊聊final这个关键字 final可以修饰类,方法和变量 final修饰的类不可以被继承 final修饰的方法不可以被覆盖 final修饰的变量是一个常量,只能被赋值一次 内部类只能访问被final修饰的局部变量 final,故名思意,就是最终的意思,由以上的五种特性,不过final的出现,也是有

Java之旅--关于多线程

关于多线程的知识,有非常多的资料可以参考.这里稍微总结一下,以求加深记忆. 关于多线程在日常工作中的使用:对于大多数的日常应用系统,比如各种管理系统,可能根本不需要深入了解,仅仅知道Thread/Runnable就够了:如果是需要很多计算任务的系统,比如推荐系统中各种中间数据的计算,对多线程的使用就较为频繁,也需要进行一下稍微深入的研究. ThreadLocal与synchronized 区别ThreadLocal 与 synchronized ThreadLocal是一个线程隔离(或者说是线程

JAVA之旅(二十二)——Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习

JAVA之旅(二十二)--Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习 继续坚持下去吧,各位骚年们! 事实上,我们的数据结构,只剩下这个Map的知识点了,平时开发中,也是能看到他的,所以还是非常值得去学习的一个知识点的,我们直接开车了 一.Map概述 泛型< k,v> 键值对,映射关系 基本特点 该集合存储键值对,是一对一对往里存,而且要保证键的唯一性 1.添加 put(key ,values) putAll() 2.删除 clear() remove(ob

java工厂类与反射机制

java 简单工厂类 2012-04-22 15:44:07|  分类: java |  标签:java工厂类  简单工厂类  |举报|字号 订阅 简单工厂模式需要由以下角色组成: 接口                        接口的实现类(简单工厂模式里面的具体产品角色)                        工厂注意对比以下三个实例的不同实例1: package org.jzkangta.factorydemo01;//定义接口interface Car{    public 

JAVA之旅(三十四)——自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫

JAVA之旅(三十四)--自定义服务端,URLConnection,正则表达式特点,匹配,切割,替换,获取,网页爬虫 我们接着来说网络编程,TCP 一.自定义服务端 我们直接写一个服务端,让本机去连接,可以看到什么样的效果 package com.lgl.socket; import java.io.IOException; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; publ

JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块

JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买电脑来说吧,首先,你不懂电脑,你去电脑城买电脑,和大象装冰箱里一样,是什么步骤?咨询 砍价 ,谈妥了就那电脑走人,对吧,这就是面向过程的思想,而面向对象是:你有一个哥们,他懂电脑,什么都会,你只要带他去,就行,你这个哥们就是对象,在JAVA中,我们就是操作一个对象去完成各种各样的操作的,这就是面向对

编程基础知识——C++能不能支持Java和ObjC的反射?

C++能不能支持Java和ObjC的反射? 要回答这个问题,首先我们要清楚什么是反射.什么是反射? 教科书的解释我就不说了,(^o^)其实我也记不得.实际开发应用的反射就是在没有某个类型的头文件或者类结构定义的情况下,存取这个类型的对象的成员字段的值,调用这个对象的成员函数(方法). 比如我有定义了一个类型 Class  A,里面有 a,b,c三个字段,有fun()函数.现在我手里只有一个 void* pA,注意它的类型只是一个void指针,我手里也没有Class的头文件,我要怎么样得到,a,b

JAVA之旅(三十三)——TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录

JAVA之旅(三十三)--TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录 我们继续网络编程 一.TCP 说完UDP,我们就来说下我们应该重点掌握的TCP了 TCP传输 Socket和ServiceSocket 建立客户端和服务端 建立连接后,通过Socket中的IO流进行数据的传输 关闭Socket 同样的,我们的客户端和服务端都是两个独立的应用 我们通过查阅API文档发现,该对象在建立的时候,就可以去连接指定主机,因为tcp是面向连接的,所以在建立socket服务时,

java学习:用反射构造bean

先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提 出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩.其中 LEAD/LEAD++ .OpenC++ .MetaXa和OpenJava

Java基础学习笔记二十三 Java核心语法之反射

类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任何类被使用时系统都会建立一个Class对象. 链接指的是将Java类的二进制代码合并到JVM的运行状态之中的过程.在链接之前,这个类必须被成功加载.类的链接包括验证.准备和解析等几个步骤. 验证:是否有正确的内部结构,并和其他类协调一致. 准备:负责为类的静态成员分配内存,并设置默认初始化值 解析: