java学习笔记09--反射机制
什么是反射:
反射是java语言的一个特性,它允许程序在运行时来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。
java的反射机制的实现要借助4个类:Class,Constructor,Field,Method 其中Class代表的是类对象,Constructor 类的构造器对象,Field 类的属性对象,Method
类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组成部分。
在正常情况下,必须知道一个类的完整路径之后才可以实例化对象,但是在java中也允许通过一个对象来找到其所在的类的信息,那么这实际上就是Class类的功能。
- package com.itmyhome;
- class A{
- }
- public class T {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- A a = new A();
- System.out.println(a.getClass().getName()); //com.itmyhome.A
- }
- }
Object类的支持
在Object类中定义了以下的方法,此方法将被所有子类继承:
public final Class getClass()
以上的方法返回值的类型是一个"Class"类,实际上此类是java反射的源头,实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。
Class类
Class本身表示一个类的本身,通过Class可以完整的得到一个类中的完整结构,包括此类中的方法定义,属性定义等。
实例化Class类对象
有三种方法实例化Class对象:
第一种:通过forName()方法
第二种:类.class
第三种:对象.getClass()
- package com.itmyhome;
- class A{
- }
- public class T {
- public static void main(String[] args) throws ClassNotFoundException {
- // TODO Auto-generated method stub
- Class<?> c1 = Class.forName("com.itmyhome.A");
- Class<?> c2 = A.class;
- Class<?> c3 = new A().getClass();
- System.out.println(c1.getName());
- System.out.println(c2.getName());
- System.out.println(c3.getName());
- }
- }
Class主要是反射的源头,不光可以取得对象所在类的信息,也可以直接通过Class类的方法进行对象的实例化操作正常情况下,使用关键字new为对象实例化,如果现在已经实例化好了Class对象,则就可以通过Class类中提供的
实例化对象
- package com.itmyhome;
- class Person {
- private String name;
- private int 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 String toString() {
- // TODO Auto-generated method stub
- return "name: " + name + ",age: " + age;
- }
- }
- public class T {
- public static void main(String[] args) throws ClassNotFoundException {
- Class<?> c = Class.forName("com.itmyhome.Person");
- Person person = null;
- try {
- person = (Person) c.newInstance(); //实例化对象
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- person.setName("itmyhome");
- person.setAge(23);
- System.out.println(person);
- }
- }
通过以上的代码,可以发现,即使不使用关键字new对象也可以进行实例化操作,反射的作用。
但是,在使用以上操作的时候有一点必须注意,在操作中类中必须存在无参构造方法,否则无法实例化
报以下异常
- java.lang.InstantiationException: com.itmyhome.Person
- at java.lang.Class.newInstance0(Class.java:340)
- at java.lang.Class.newInstance(Class.java:308)
- at com.itmyhome.T.main(T.java:35)
- Exception in thread "main" java.lang.NullPointerException
- at com.itmyhome.T.main(T.java:41)
对于以上的程序也并非没有解决的方法,也是可以通过其他的方式进行实例化操作的,只是在操作的时候需要明确的调用类中的构造方法,并将参数传递进去之后才可以进行实例化操作,操作步骤如下:
1、通过Class类中的getConstructors()取得本类中的全部构造方法。
2、向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数。
3、之后通过Constructor实例化对象。
- package com.itmyhome;
- import java.lang.reflect.Constructor;
- class Person {
- private String name;
- private int age;
- public Person(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 String toString() {
- // TODO Auto-generated method stub
- return "name: " + name + ",age: " + age;
- }
- }
- public class T {
- public static void main(String[] args) throws ClassNotFoundException{
- Class<?> c = Class.forName("com.itmyhome.Person");
- Constructor<?> cons[] = c.getConstructors();
- Person person = null;
- try {
- person = (Person) cons[0].newInstance("itmyhome",23); //实例化对象
- } catch (Exception e) {
- e.printStackTrace();
- }
- person.setName("itmyhome");
- person.setAge(23);
- System.out.println(person);
- }
- }
反射机制的深入----取得类的结构
在实际开发中,以上的程序就是反射应用最多的地方,当然,反射机制所提供的功能远不止如此,还可以通过反射得到一个类的完整结构,那么这就要使用到java.lang.reflect包中的以下几个类:
Constructor:表示类中的构造方法
Field:表示类中的属性
Method:表示类中的方法
这三个类都是AccessibleObject类中的子类
- package com.itmyhome;
- interface IPerson{
- public static final String NAME = "itmyhome";
- public String toSay();
- public String toEat(String name,int age);
- }
- class Person implements IPerson{
- private String name;
- private int age;
- public Person(){ //无参构造
- }
- public Person(String name,int age){
- this.name = name;
- this.age = age;
- }
- @Override
- public String toSay() {
- return "hello!";
- }
- @Override
- public String toEat(String name, int age) {
- return "name: "+name+",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;
- }
- }
取得类所实现的全部接口
要想取得一个类所实现的全部接口,则必须使用Class类中的getInterfaces()方法,此方法定义如下:
- public Class[] getInterfaces()
此方法返回一个Class类的对象数组,之后就可以直接利用Class类中的getName()方法输出即可。
因为一个类可以同时实现多个接口,所以在此处就以一个数组的形式返回实现的全部接口。
- public class T {
- public static void main(String[] args) throws Exception{
- Class<?> cl = Class.forName("com.itmyhome.Person"); //实例化对象
- Class<?> c[] = cl.getInterfaces(); //以数组形式返回实现的全部接口
- for (int i = 0; i < c.length; i++) {
- System.out.println(c[i].getName()); //输出接口名称
- }
- }
- }
取得类所继承的父类
一个类可以实现多个接口,但是只能继承一个父类,所以如果要想取得一个类的父类,可以直接使用Class类中的getSuperClass()方法。此方法定义如下:
- public Class<? super T> getSuperClass()
此方法返回的是Class实例,和之前的得到接口一样,可以通过getName()方法取得名次。
一个类只继承一个父类,如果一个类中没有明确的指明继承哪个类,则肯定继承的是Object类。
- public class T {
- public static void main(String[] args) throws Exception{
- Class<?> cl = Class.forName("com.itmyhome.Person"); //实例化对象
- Class<?> c = cl.getSuperclass(); //取得继承父类
- System.out.println(c.getName());
- }
- }
取得类中的全部构造方法
- public class T {
- public static void main(String[] args) throws Exception{
- Class<?> cl = Class.forName("com.itmyhome.Person"); //实例化对象
- Constructor<?> c[] = cl.getConstructors();
- for (int i = 0; i < c.length; i++) {
- System.out.println(c[i]);
- }
- }
- }
取得类中的方法
要想取得一个类中的全部方法,可以使用Class类中的getDeclaredMethods()方法,此方法返回一个Method类的对象数组,而如果要想进一步取得方法的具体信息,例如:方法的参数,抛出的异常等等,则就必须依靠Method类
public Method[] getDeclaredMethods() 输出本类中的全部方法
public Method[] getMethods() 输出全部的方法
- public class T {
- public static void main(String[] args) throws Exception{
- Class<?> cl = Class.forName("com.itmyhome.Person"); //实例化对象
- Method m1[] = cl.getMethods();
- for (int i = 0; i < m1.length; i++) {
- System.out.println(m1[i]);
- }
- System.out.println("*************");
- Method m2[] = cl.getDeclaredMethods();
- for (int i = 0; i < m2.length; i++) {
- System.out.println(m2[i]);
- }
- }
- }
取得类中的属性
public Field[] getFields() 得到实现的接口和父类中的公共属性
public Field[] getDeclaredFields() 得到本类中的全部属性
以上方法返回的都是Field的数组,每一个Field对象就表示类中的一个属性
- public class T {
- public static void main(String[] args) throws Exception{
- Class<?> cl = Class.forName("com.itmyhome.Person"); //实例化对象
- Field f1[] = cl.getFields();
- for (int i = 0; i < f1.length; i++) {
- System.out.println(f1[i]);
- }
- System.out.println("*********");
- Field f2[] = cl.getDeclaredFields(); //本类中的属性
- for (int i = 0; i < f2.length; i++) {
- System.out.println(f2[i]);
- }
- }
- }
java学习笔记09--反射机制的更多相关文章
- java学习笔记13--反射机制与动态代理
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...
- java学习笔记:反射
1.什么是反射? Reflection(反射)是被视为动态语言的关键,反射机制允许程序做执行期间借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象内部属性及方法 2.反射相关的 ...
- 8.2(java学习笔记)反射
一.基础知识 对象是表示或封装一些数据,一个类被加载后JVM会创建一个对应该类的Class对象, 类的整个结构信息会被放在对应的对象中,通过这个对象我们可以获取改类的全部信息, 而这些操作称为反射. ...
- Java 学习笔记(15)——反射
Java中的类文件最终会被编译为.class 文件,也就是Java字节码.这个字节码中会存储Java 类的相关信息.在JVM执行这些代码时首先根据 java 命令中指定的类名找到.class 文件然后 ...
- java学习笔记之反射—反射和工厂模式
简单工厂模式又称为静态工厂方法模式,它是由工厂对象来决定要创建哪一种类的实例化对象. 静态工厂代码: class Factory{ private Factory() {} public static ...
- 【java学习笔记】反射基础
一.反射 反射就是在剖析一个类,了解这个类的构造,创建这个类对应的对象. Class 代表字节码的类,代表类的类 Field 代表属性的类 Method 代表方法的类 Constructor 代表构造 ...
- java学习笔记之反射—Class类实例化和对象的反射实例化
反射之中所有的核心操作都是通过Class类对象展开的,可以说Class类是反射操作的根源所在,但是这个类的实例化对象,可以采用三种方式完成. java.lang.Class类的定义: public f ...
- Java学习笔记__异常机制_try_catch_finally_return执行顺序
package cn.xiaocangtian.Exception; import java.io.FileInputStream; import java.io.FileNotFoundExcept ...
- 1.13(java学习笔记)异常机制
异常不同于错误,它是程序运行时产生的未知问题. 如果把程序比喻成一辆汽车,那么汽车开着开着突然前面出现了一个大石头挡住了路,这就叫异常. 那么出现了这个异常我们需要去处理,比如打电话给公路管理局,让它 ...
随机推荐
- Linux 经典电子书共享下载
Linux 经典电子书共享下载 Linux网络管理员指南--Linux领域两位领导人物的作品—相当于“Linux 文档项目”.rar vim用户手册_603.0.pdf [Linux系统管理技术手册( ...
- 技术不牛如何才拿到国内IT巨头的Offer(转)
不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,NOI金牌,开源社区名人,三年级开始写Basic...在跪拜之余我们不禁要想,和这些牛人比,作为绝大部分技 ...
- .NET vs JAVA
一个同事写一个方案,让我补充下.NET和 JAVA语言的优缺点,以下是我的回复: 老X你好! 我觉得这个问题,本质上不是java和.net两个开发语言方面的比较,单纯从这两个开发语言来讲,部分伯仲,在 ...
- 基于visual Studio2013解决C语言竞赛题之1016循环打印矩阵
题目 解决代码及点评 /* 找规律,编程序打印6×6的矩阵: 1 2 3 5 8 13 1 4 9 17 30 51 1 6 19 45 92 173 . . . */ ...
- XML文件解析之--DOM与SAX
xml文件又称‘可扩展性标记语言’,可以对文档和数据进行结构化处理,从而能够在部门.客户和供应商之间进行交换,实现动态内容生成,企业集成和应用开发. 我们在进行web开发的时候离不开xml文件,xml ...
- Javascript 进阶 封装
js中处处是对象,面向对象的第一步当然就是封装了,由于Js中没有类的概念,所以封装起来也比较麻烦,下面介绍两种js的封装. 1.使用约定优先的原则,将所有的私有变量以_开头 <script ty ...
- Oracle 经常使用的改动语句
一.表Table 測试表:MY_TEST_TABLE -- Create table create table MY_TEST_TABLE ( A VARCHAR2(30), B NUMBER(10) ...
- 能上QQ无法上网
不少网友碰到过或亲身经历过电脑QQ还在登录,并且还能正常聊天,但是却打不开网站网页的情况,而当电脑出现能上qq但是打不开网页是由什么原因引起,我们又该如何解决类似的电脑故障呢. 适用范围及演示工具 适 ...
- Android中吐司当前电池电量
/** * * @author chrp * *土司当当电池电量 */ public class MainActivity extends Activity { class BtteryReceive ...
- Servlet的学习之Session(1)
在学习完了Servlet中的Cookie技术后,我们再来学习另一个能保存会话数据的技术——Session. Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其 ...