正常情况下,单纯的做开发是接触不到反射机制的(额,当然并不排除例外的情况了)。下面我就对我学到的反射方面的知识做一个小小的总结,旨在复习和以后的查看。


原理分析:

所谓反射就是将一个类当做我们研究的对象,进行分解,获取其中的内容的过程。其核心就是Class类,他是所有类的研究的对象,基于Class我们就可以获取一个类的字节码,进而获取想要的值。

目标类(待解刨的类)



package reflect;

public class Person {

    public Person(){}

    private String name;
    public int address;

    public int getAddress() {
        return address;
    }

    public void setAddress(int address) {
        this.address = address;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person(String name ){
        this.name = name;
    }

    public String getName(){
        return this.name;
    }

    private Person(int name){
        System.out.println("这里是私有的带有参数的构造方法!");
    }

    public void eat(){
        System.out.println("吃饭!");
    }

    public void drink(String name){
        System.out.println("正在喝 :"+ name);
    }

    public void purchase(String address ,int [] number , String [] item){
        System.out.println("这个人在  " + address +"  买了 "+item +"  分别  "+ number+" 个!");
    }

    private String flay(String tool){
        return "I Can Flay By "+ tool;
    }

    public static String spend(String money){
        System.out.println("我只能够花费 "+money +"钱!");
        return "你造吗?";
    }

    public static void main(String[] args) {
        System.out.println(args[0]);
    }

}

反射构造方法小例子


package reflect;

import java.lang.reflect.Constructor;

import org.junit.Test;

public class ReflectConstructor {

    /**
     * 反射得到无参的构造函数的方法
     * @throws Exception
     */
    @Test
    public void reflect1() throws Exception{
        Class cls = Class.forName("reflect.Person");
        Constructor c = cls.getConstructor(null);
        Person person = (Person) c.newInstance(null);
        System.out.println("反射得到的结果是:"+ person.toString());
    }

    /**
     * 反射出带有参数的构造方法
     * @throws Exception
     */
    @Test
    public void reflect2() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Constructor c = cls.getConstructor(String.class);
        Person person = (Person) c.newInstance("Name");
        System.out.println("反射获得的有参的结果是:"+ person.getName());
    }

    /**
     * 反射出私有的带有参数的构造方法
     * @throws NoSuchMethodException
     * @throws Exception
     */
    @Test
    public void reflect3() throws NoSuchMethodException, Exception {
        Class cls = Class.forName("reflect.Person");
        Constructor c = cls.getDeclaredConstructor(int.class);
        //java语言默认私有的方法是不能被外界访问的到的,但要进行强制的访问需要加上一层权限
        c.setAccessible(true);
        Person person = (Person) c.newInstance(201492115);

        System.out.println("反射出私有的带有参数的构造方法!"+ person.toString());
    }

}

反射所有方法的小例子


package reflect;

import java.lang.reflect.Method;

import org.junit.Test;

public class ReflectMethods {

    /**
     * 反射测试一个无参的方法
     * public void eat()
     * @throws Exception
     */
    @Test
    public void feflect1() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method =cls.getMethod("eat", null);
        System.out.println(method.toString());
        method.invoke(new Person(), null);
        method.invoke(cls.newInstance(), null);
    }

    /**
     * 反射测试一个带有参数的方法
     * public void drink(String name)
     * @throws Exception
     */
    @Test
    public void reflect2() throws  Exception {

        Class cls = Class.forName("reflect.Person");
        Method method =cls.getMethod("drink", String.class);
        System.out.println(method.toString());
        method.invoke(new Person(), "中国凉茶");
        method.invoke(cls.newInstance(), "中国凉茶");
    }

    /**
     * 反射测试含有多个复杂类型的参数的方法
     * public void purchase(String address ,int [] number , String [] item)
     * @throws Exception
     */
    @Test
    public void reflect3() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getMethod("purchase", String.class,int[].class,String[].class);
        method.invoke(cls.newInstance(), "大连",new int[]{1,2,3},new String[]{"鱿鱼","贝壳","螃蟹"});
    }

    /**
     * 反射测试一个带有返回值的不含参数的方法
     * public String getName()
     * @throws Exception
     */
    @Test
    public void reflect4() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getMethod("getName", null);
        String result = (String) method.invoke(cls.newInstance(), null);
        System.out.println("测试带有返回值的无参的方法,所得的结果是: "+result);

    }

    /**
     * 反射测试私有含参数的方法
     * private String flay(String tool)
     */
    @Test
    public void reflect5() throws Exception {

        Class cls = Class.forName("reflect.Person");
        //对于私有的方法只能通过getDeclaredMethod方式得到
        Method method = cls.getDeclaredMethod("flay", String.class);
        //记得强制将访问人权限提升起来到"可以访问的到"
        method.setAccessible(true);
        String result = (String) method.invoke(cls.newInstance(), "蝙蝠侠的风衣!");
        System.out.println("反射测试私有的含参数的方法的结果是: "+ result);
    }

    /**
     * 反射测试私有的含参数的静态的方法
     * public static String spend(String money)
     */
    @Test
    public void reflect6() throws Exception {

        Class cls = Class.forName("reflect.Person");
        //对于静态的方法只能通过getDeclaredMethod方式得到
        Method method = cls.getDeclaredMethod("spend", String.class);

        String result = (String) method.invoke(cls.newInstance(), "100000000000000元人民币!");
        System.out.println("反射测试私有的含参数的方法的结果是: "+ result);
    }

    /**
     * 反射测试主方法
     * public static void main(String[] args)
     * @throws Exception
     */
    @Test
    public void reflect7() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Method method = cls.getMethod("main",String[].class);
        method.invoke(null, (Object)new String[]{"A","B","C"});
    }

}

反射字段值的小例子


package reflect;

import java.lang.reflect.Field;

import org.junit.Test;

public class ReflectField {

    /**
     * 反射测试字段(属性)的值
     * public int address
     * @throws Exception
     */
    @Test
    public void reflect1 () throws Exception {
        Class cls = Class.forName("reflect.Person");
        Field field = cls.getField("address");
        String result = field.getName();
        System.out.println("反射所得的字段的结果是:"+result);
    }

    /**
     * 反射测试私有的属性(字段)的结果
     * private String name
     * @throws Exception
     */
    @Test
    public void reflect2() throws Exception {
        Class cls = Class.forName("reflect.Person");
        Field field = cls.getDeclaredField("name");
        field.setAccessible(true);
        String result = field.getName();
        System.out.println("反射测试所得的私有的字段(属性)的值为:"+ result);
    }

}

我的总结


  • 全部的反射方法均交给JUnit测试通过,并没有发现出错的地方
  • 反射是一个比较灵活的方式,具体情况一定要灵活的变通
  • 对于私有的变量或者方法,要想访问到其值,就必须打开访问的权限即设置为setAccessable(true);
  • 对于框架的运行,需要给出一个类的完整名称(包含完整的包名),这样才不会出错!

Java 学习之反射机制“解刨”分解类,并获取内容!的更多相关文章

  1. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  2. java学习--Reflection反射机制

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...

  3. Java学习:反射机制简介

    反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为ja ...

  4. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  5. JAVA 学习笔记 - 反射机制

    1.   JAVA反射机制的概念 2. 怎样实例化一个 Class对象 Class.forName(包名.类名); 对象.getClass(); 类.class; ================== ...

  6. Java学习笔记-反射机制

    Java反射机制实在运行状态时,对于任意一个类,都能够知道这个类的属性和方法,对于任意一个对象,都能够调用他的任意一个属性和方法 获取Class对象的三种方式 Object类中的getClass()方 ...

  7. Java中的反射机制Reflection

    目录 什么是反射? 获取.class字节码文件对象 获取该.class字节码文件对象的详细信息 通过反射机制执行函数 反射链 反射机制是java的一个非常重要的机制,一些著名的应用框架都使用了此机制, ...

  8. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  9. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

随机推荐

  1. JAVA NIO工作原理及代码示例

    简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...

  2. 解决nodejs中json序列化时Date类型默认为UTC格式

    在nodejs中,json序列化时Date类型时,默认转为UTC格式. 如下图 上面只是一个例子,下面我用一个更具体化的例子来展示一个这个情况,我们在开发WEB项目中,经常用到Express组件, 我 ...

  3. Cisco 的基本配置实例之四----vlan的规划及配置(接入交换机)

    4.2 接入交换机的相关配置 ## 在此例中,我们联入的是一台接入交换机,此交换机的gi0/1口上联至核心交换机.也就意味着我们需要配置gi0/1为trunk口.具体的配置如下: D-2960-3(c ...

  4. sqlserver 查询 inner join 同一表2次 只出一条查询结果

    inner join T_MTN_MobileNumber k on 1=1 and k.hddm='01' inner join (select a.hdxx+','+b.hdxx as hdxx ...

  5. Linux上rpm实战搭建FTP服务器

    1.检测是否已安装FTP服务 # rpm -qa|grep vsftpd 2.未安装ftp服务的前提进行使用rpm安装 # yum install vsftpd -y Loaded plugins: ...

  6. 日历类和日期类转换 并发修改异常 泛型的好处 *各种排序 成员和局部变量 接口和抽象类 多态 new对象内存中的变化

    day07 ==和equals的区别? ==用于比较两个数值 或者地址值是否相同.  equals 用于比较两个对象的内容是否相同   String,StringBuffer.StringBuilde ...

  7. 浏览器本地下拉框查询选择js

    首先需要引用jquery-1.7.2.js. 页面下拉框有对应的数据,此下拉框的查询将不与服务器交互.本地下拉框查询.暂不支持通过键盘上下按键和enter键控制 // JavaScript Docum ...

  8. C++框架_之Qt的窗口部件系统的详解-上

    C++框架_之Qt的窗口部件系统的详解-上 第一部分概述 第一次建立helloworld程序时,曾看到Qt Creator提供的默认基类只有QMainWindow.QWidget和QDialog三种. ...

  9. Sharding-jdbc实现分库分表

    首先在pom文件中引入需要的依赖 <dependency> <groupId>io.shardingjdbc</groupId> <artifactId> ...

  10. Android开发技巧——定制仿微信图片裁剪控件

    拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...