JAVA 反射特性

1.   反射(概念):程序在运行期可以改变程序结构和变量类型,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

2.   反射的特性:

•在运行时判断任意一个对象所属的类

•在运行时构造任意一个类的对象

•在运行时判断任意一个类所具有的成员变量和方法

•在运行时调用任意一个对象的方法

3. 反射的前传:类类型   Class Class     java中有一个类很特殊,就是Class类,大家就可以把它理解为封装了类的信息,很多解释说Class类没有构造器,其实是有的,

只不过它的构造方法是private的(构造函数设置成private,这样是为了禁止开发者去自己创建Class类的实例,就像单例模式中的构造方法一样要用private)。我们可以看一下JDK中源码:

 class Class<T> implements java.io.Serializable,
                  java.lang.reflect.GenericDeclaration,
                  java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
    static {
        registerNatives();
    }

    /*
     * Constructor. Only the Java Virtual Machine creates Class
     * objects.
     */
    private Class() {}

  ..... 

注释很明确的告诉了我们,这个类是有JVM来创建的,所以我们就不用麻烦了。如果我们拿到一个类的类型信息,就可以利用反射获取其各种成员以及方法了。  (注:Class 从JDK1.5版本后就开始更多为泛型服务了)那么我们怎么拿到一个类型的信息呢?假设我们有一个Monkey类:

4.    获取类的构造器    

首先介绍一下Constructor类,这个类用来封装反射得到的构造器,Class有四个方法来获得Constructor对象

•public Constructor<?>[] getConstructors()              返回类中所有的public构造器集合,默认构造器的下标为0

•public Constructor<T> getConstructor(Class<?>... parameterTypes)     返回指定public构造器,参数为构造器参数类型集合

•public Constructor<?>[] getDeclaredConstructors()        返回类中所有的构造器,包括私有

•public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

返回任意指定的构造器    从名字来看,还是很好懂的,带上Declared的都是获得所有的构造方法,包括私有,哈,这下我们就可以调用原本不允许调用的私有构造器了,看代码

/**  2          * 获取构造方法Constructor

3          * getConstructor()  only for public

4          * getDeclaredConstructor()  global access all

5          *

6          * */

7

8         //指定参数列表获取特定的方法

9         Constructor con = cls1.getDeclaredConstructor(new Class[]{String.class});

10         con.setAccessible(true); //设置可访问的权限

11         Object obj = con.newInstance(new Object[]{"liyang"});

12         System.out.println(obj);  //打印一下这个对象的信息

13

14 //获取所有的构造方法集合

15         Constructor con1[] = cls1.getDeclaredConstructors();

16         con1[1].setAccessible(true);

17         Object obj1 = con1[1].newInstance(new Object[]{"tom"});

18         System.out.println(obj1);

5.   获取类的成员变量

•public Field getDeclaredField(String name)    获取任意指定名字的成员

•public Field[] getDeclaredFields()              获取所有的成员变量

•public Field getField(String name)             获取任意public成员变量

•public Field[] getFields()                        获取所有的public成员变量

/**2          * 获取成员变量Field

3          * getField()

4          * getDeclaredField()

5          * */

6         Field mem = cls1.getDeclaredField("name");

7         mem.setAccessible(true);

8         System.out.println("we get form field :"+mem.get(obj));

6.  获取类的方法

•public Method[] getMethods()    获取所有的共有方法的集合

•public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合

•public Method[] getDeclaredMethods()  获取所有的方法

•public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

7.

本文引用:  http://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html

http://www.cnblogs.com/octobershiner/archive/2012/03/18/2404751.html

时间: 2024-12-22 08:43:23

JAVA 反射特性的相关文章

Java反射特性--获取其他类实例并调用其方法

1. 代码结构 .├── com│   └── test│   └── MyTest.java└── MainCall.java 2. 代码内容 MyTest.java: package com.test; public class MyTest { public void do_test() { System.out.println("Doing test...\n"); } } MaiCall.java import java.lang.reflect.Method; public

mybatis批量提交

之前在做项目时,使用mybatis,批量执行sql,这里简单写下步骤 在配置数据库连接时,加入一个参数,例如 jdbc:mysql://127.0.0.1:3307/mvs-report?allowMultiQueries=true 在mybatis执行时传入list集合参数, 在mybatis的xml文件中拼装sql,例如 <insert id="batchInsert" parameterType="java.util.List" > insert

Java学习:动态代理的一点小理解

手动实现 之前的一篇讲IoC的博文提到了代理模式,事实上代理模式就是AOP实现的重要基石.但是上面的代码有一个显而易见的缺陷,也就是之前讲解反射内容时提到的:不具备动态性. 上面代码中的Server就像是反射理解博文中提到的工厂订单管理员一样,每增加一样菜系,就需要相应更新手上的菜单.类比反射特性,我们完全可以做到让服务员不需要手上拿着菜单来为顾客服务: // 服务员实现类 public class ServerImpl implements Server { // 采用组合的方式引入noodl

Java多线程学习(吐血超详细总结)

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么要用join方法 七常见线程名词解释 八线程同步 九线程数据传递 本文主要讲了java中多线程的使用方法.线程同步.线程数据传递.线程状态及相应的一些线程函数用法.概述等. 首先讲一下进程和线程

Java TM 已被阻止,因为它已过时需要更新的解决方法

公司的堡垒机需要通过浏览器登陆,且该堡垒机的网站需要Java的支持,最近通过浏览器登陆之后总是提示"java TM 已被阻止,因为它已过时需要更新的解决方法"导致登陆之后不能操作, 但是操作系统中确实已经安装了比较新的JDK,安装的JDK版本是jdk-7u67-windows-i586,因为太烦人,所以决定搞清楚报错的原因,一劳永逸,彻底解决这个问题 准备工作:安装JDK,安装版本jdk-7u67-windows-i586.exe,因为机器的Eclipse还依赖64位的JDK,所以另安

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 1 2 3 4 5 6 7 new Thread(new

由@NotNull 注解引出的关于Java空指针的控制(转)

Java 小技巧和在java应用避免NullPonintException的最佳方法 在java应用程序中,一个NullPonintException(空指针异常)是最好解决(问题)的方法.同时,空指针也是写健壮的顺畅运行的代码的关键.“预防好过治疗”这句话也同样适用于令人不爽的NullPonintException.通过应用防御性的编码技术和在遵守多个部分之间的约定,你可以再很大程度上避免NullPointException.下面的这些java小技巧可以最小化像!=null这种检查的代码.作为

Java注解(2)-注解处理器(运行时|RetentionPolicy.RUNTIME)

如果没有用来读取注解的工具,那注解将基本没有任何作用,它也不会比注释更有用.读取注解的工具叫作注解处理器.Java提供了两种方式来处理注解:第一种是利用运行时反射机制:另一种是使用Java提供的API来处理编译期的注解. 反射机制方式的注解处理器 仅当定义的注解的@Retention为RUNTIME时,才能够通过运行时的反射机制来处理注解.下面结合例子来说明这种方式的处理方法. Java中的反射API(如java.lang.Class.java.lang.reflect.Field等)都实现了接

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个