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

  Class 类 ,一个Class对象将表示一个类的属性;获取Class类一共有三种方式如下

package javase.first;

 /**
 * @author fqh
 * @Date 2017年4月12日:上午8:15:01
 */
public class Employee {

    //属性,私有化属性,并提供方法让其能够通过方法访问
    private String name;
    private int age;
    private double salary;

    private static final int NUMBER=217; //常量

    private static void method1(){

        System.out.println("静态方法");
    }
    static{

        System.out.println("静态块");
    }
    public Employee(){

    }
    //构造器
    public Employee(String name,int age,double salary){

        this.name=name;
        this.age=age;
        this.salary=salary;
        System.out.println("构造器");
    }

    public void raiseSalary(double multiple){
        this.salary *= multiple;
    }

    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 double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

}
    @Test
    public void testReflect() {

        Employee e =new Employee("fqh", 23, 5000);
        Class class1 = null;
        Class class2 = null;
        Class class3 = null;
        try {
            //推荐这种
             class1 = Class.forName("javase.first.Employee");
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        //第二种
        class2=Employee.class;
        //第三种
        class3=e.getClass();
        System.out.println(class1.getName()+" "+e.getName());//通过Class。getName()可以获取类名
        System.out.println(class2.getName()+" "+e.getName());//通过Class。getName()可以获取类名
        System.out.println(class3.getName()+" "+e.getName());//通过Class。getName()可以获取类名
    }
    

  例如加载jdbc驱动的时候Class.forName("com.mysql.jdbc.Driver");

  假如我需要获取类的属性方法等等,该怎么做呢?

@Test
    public void testReflect2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException {

        Class class1 = null;
        try {
            //推荐这种
             class1 = Class.forName("javase.first.Employee");
        } catch (ClassNotFoundException e1) {
            e1.printStackTrace();
        }
        System.out.println(class1.getName());//通过Class。getName()可以获取类名
        System.out.println("===============本类属性===============");
        //获取所有属性  ,getFields()是获取所有公有的方法
        Field[] fields =class1.getDeclaredFields();
        for(Field f:fields)
        {
            // 权限修饰符
            int mo = f.getModifiers();
            String priv = Modifier.toString(mo);
            // 属性类型
            Class<?> type = f.getType();
            System.out.println(priv + " " + type.getName() + " " + f.getName() + ";");
        }
        System.out.println("===============本类方法===============");
        Method[] methods =class1.getDeclaredMethods();
        for(Method f:methods)
        {
            // 权限修饰符
            int mo = f.getModifiers();
            String priv = Modifier.toString(mo);
            // 属性类型
            Class<?> type = f.getReturnType();
            System.out.println(priv + " " + type.getName() + " " + f.getName() + ";");
        }
        System.out.println("===============通过反射机制调用方法===============");
            Object obj = class1.newInstance();
            Method method = class1.getMethod("setName", String.class);
            method.invoke(obj,"fqh");
            method = class1.getMethod("getName");
            method.invoke(obj);
            Employee e = (Employee) obj ;
            System.out.println(e.getName());
        System.out.println("===============通过反射机制修改属性===============");
            Field field =class1.getDeclaredField("name");
            // 可以直接对 private 的属性赋值
            field.setAccessible(true);//将属性设为可修改
            field.set(obj, "Java反射机制");
            System.out.println(field.get(obj));
    }    

  将反射应用在工厂方法

interface fruit {
    public abstract void eat();
}
class Apple implements fruit {
    public void eat() {
        System.out.println("Apple");
    }
}
class Orange implements fruit {
    public void eat() {
        System.out.println("Orange");
    }
}
class Factory {
    public static fruit getInstance(String ClassName) {
        fruit f = null;
        try {
            f = (fruit) Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}
/**
 * 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
 * Java 工厂模式可以参考
 * http://baike.xsoftlab.net/view/java-factory-pattern
 *
 * 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
 *
 * 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
 *
 * java 读取 properties 配置文件 的方法可以参考
 * http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file
 *
 * @author xsoftlab.net
 */
public class TestReflect {
    public static void main(String[] args) throws Exception {
        fruit f = Factory.getInstance("net.xsoftlab.baike.Apple");
        if (f != null) {
            f.eat();
        }
    }
}

从零开始学java (四)反射的更多相关文章

  1. 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)

    Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...

  2. 从零开始学 Java - 利用 Nginx 负载均衡实现 Web 服务器更新不影响访问

    还记得那些美妙的夜晚吗 你洗洗打算看一个小电影就睡了,这个时候突然想起来今天晚上是服务器更新的日子,你要在凌晨时分去把最新的代码更新到服务器,以保证明天大家一觉醒来打开网站,发现昨天的 Bug 都不见 ...

  3. 从零开始学 Java - Spring AOP 实现用户权限验证

    每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...

  4. 从零开始学 Java - Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  5. 从零开始学 Java - CentOS 下安装 Nginx

    早上下起了暴雨 闹钟还未响起就听到雨滴哗啦啦击打窗户的声音,被吵醒了.起床上班,在楼下的十字路口,暴雨大到完全看不清对面,两个穿着雨衣的交警站在路口中间指挥着过往的车辆,大家都慌慌张张.急急忙忙的打着 ...

  6. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  7. 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)

    硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...

  8. 从零开始学 Java - 我放弃了 .NET ?

    这不是一篇引起战争的文章 毫无疑问,我之前是一名在微软温暖怀抱下干了近三年的 .NET 开发者,为什么要牛(sha)X一样去搞 Java 呢?因为我喜欢 iOS 阿!哈哈,开个玩笑.其实,开始学 Ja ...

  9. 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)

    从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...

  10. 从零开始学 Java - log4j 项目中的详细配置

    你还会用笔来写字么 我是不怎么会了,有时候老是拿起笔之后不知道这个字怎么写,这时候就会拿起手机去打出来:有时候还会写出来这个字之后越看越不像,这时候就开始怀疑自己的能力了:有时候写出来了一大堆字之后, ...

随机推荐

  1. 嵌入式文件IO实验

    实验步骤: 1.arm-linux-gcc 交叉编译环境的安装.参考网站:https://jingyan.baidu.com/article/9c69d48f80282013c9024e20.html ...

  2. JAVA设计方法思考之如何实现一个方法执行完毕后自动执行下一个方法

    今天编程时,突然想起来在一些异步操作或Android原生库的时候,需要我们实现一些方法, 这些方法只需要我们具体实现,然后他们会在适当的时候,自动被调用! 例如AsyncTask,执行玩doInBac ...

  3. Servlet中response、request乱码问题解决

    Java Web(二) Servlet中response.request乱码问题解决   三月不减肥,五月徒伤悲,这就是我现在的状态,哈哈~ 健身.博客坚持. --WH 一.request请求参数出现 ...

  4. C语言语法

    1.函数指针类型定义,然后指针结构体类型定义,最后的调用形式为aaa.bbb();(aaa为结构体变量)或者 aaa->bbb();(aaa为结构体指针),函数指针最好用结构体封装起来变成指针结 ...

  5. Java基础知识思维导图

     

  6. js生成二维码并保存成图片下载

    我这里使用是jQuery,和jquery.qrcode.js,需要的可以自己找链接下载.示例代码仅做参考 html代码: <a id="downloadLink">&l ...

  7. windows 下用命令来操作定时任务

    cmd下定时执行命令可以使用 at 命令 或者 schtasks命令.at 语法:at +时间+运行程序schtasks语法:schtasks /creat /tn 设定定时运行的名字 /tr “运行 ...

  8. C博客01--顺序、分支结构

    1.本章学习总结 1.1 思维导图 1.2 本章学习体会及代码量学习体会 1.2.1 学习体会 经过一周的初步学习,对C语言我有了一定的认识,也体验到了代码的乐趣,这应该为我以后的学习开了一个好头.在 ...

  9. html初识form表单

    定义和用法 <form> 标签用于为用户输入创建 HTML 表单. 表单能够包含 input 元素,比如文本字段.复选框.单选框.提交按钮等等. 表单用于向服务器传输数据.通过submit ...

  10. Spring:MVC

    摘要 Spring MVC 是一个开源的.基于MVC架构的WEB应用框架.这里记录MVC模型的概念以及Spring MVC 的请求处理流程. 关键词:Spring MVC 一.什么是Spring MV ...