从零开始学java (四)反射

  反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为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();
        }
    }
}

时间: 2024-12-15 14:18:42

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

从零开始学java之出入门卫管理系统(三)

  这个系统包含了四块,第一块就是人员管理,经理分配三位分别有"ABC"权限的人,分别管理请假申请,请假审批,门卫登记管理.同时不属于本公司的内部人员,如别的公司的人员如果想到本公司访问,也是先通过这"ABC"权限的三个人代为写来访申请,来访审批,来访门卫登记管理.     具体步骤如下:     因为后面都会用到很多相同的方法,和相同的属性,所以我先建立了两个接口让后面的方法类和属性类都实现这两个接口,这样就降低了耦合度.     从零开始学Java之出入门卫管理

从零开始学Java之出入门卫管理(二)

    这个系统包含了四块,第一块就是人员管理,经理分配三位分别有"ABC"权限的人,分别管理请假申请,请假审批,门卫登记管理.同时不属于本公司的内部人员,如别的公司的人员如果想到本公司访问,也是先通过这"ABC"权限的三个人代为写来访申请,来访审批,来访门卫登记管理.     具体步骤如下:     因为后面都会用到很多相同的方法,和相同的属性,所以我先建立了两个接口让后面的方法类和属性类都实现这两个接口,这样就降低了耦合度.     从零开始学Java之出入门卫

如何从零开始学Java编程

Java语言的学习开始,很多同学不知道从哪入手?如果你也想知道如何从零开始学Java?怎样学Java最有效? 虽然Java面象对象很多东西都是被封装好的直接用,相对其他语言没那么复杂,但是学的东西也没有那么的so easy,总之如果你是真想做开发,就先沉下心用心把基础打好,不要先老想着因为软件行业有市场,所以要进来分一杯羹的这种急躁心态. 另外,在编程这个行业,技术更新速度快,所以一定要具备相应的自学能力及自学意识,不然即使现在入职了Java相关的工作,不主动学习的话,说不定几年后你就跟不上技术

Java从零开始学十四(包和访问控制)

一.java中的包 Java文件的组织形式Windows中的文件功能类似 在开发比较大的项目时,不可能只涉及到一个java文件,可能要创建几十,甚至几百个java文件,这个时候,我们就可以使用包,把相关的java文件放在一起,利用包来方便,快捷,有效的管理这些文件 包的引入还可以避免命名冲突的问题,不同包下的类名可以同名 二.定义包 package 包名 这条语句必须放在java源程序的第一行,前面不能有任何可执行代码,当然注释除外 包可以创建多层次的,不同层次之间用点(.)隔开和windows

从零开始学JAVA(08)-使用SpringMVC4 Restful 风格引用静态文件 css/js/png

在写完helloworld后想给网页加点样式(*.css),结果怎么也显示不了,百度了很多种方法后试行尝试,试验成功并记录下来,方便以后查看. 时隔两年,继续学习JAVA,太久没学了,忘记得差不多,还好以前写的helloworld,还能用. 一.关于开发环境 eclipse-jee-neon-1a-win32 Jdk 1.8u112 (32位版本) SpringMVC 4.3.4.RELEASE apache-tomcat-8.5.8 二.helloworld.jsp文件中的引用的样式表为 st

从零开始学JAVA(09)-使用SpringMVC4 + Mybatis + MySql 例子(注解方式开发)

项目需要,继续学习springmvc,这里加入Mybatis对数据库的访问,并写下一个简单的例子便于以后学习,希望对看的人有帮助.上一篇被移出博客主页,这一篇努力排版整齐,更原创,希望不要再被移出主页了. 原创文章,后面附上源码,转载请注明出处http://www.cnblogs.com/lin557/p/6179618.html 一.运行环境 Eclipse Neon.1a Release (4.6.1) 官网下载 mysql-5.7.16-winx64(http://cdn.mysql.co

从零开始学JAVA(06)-WebService_Jersey_Restful

由于项目上需要写一个简单的评价系统,像银行MM前面的那种非常满意.满意.不满意那种,结合一个安卓的APP一起使用.由于使用3G网页通讯,个人认为http这种方式更合适.曾经听在Delphi鸟窝群的白雪公猪大神讲过,我们这种情况下的APP应用在移动网络下使用长连接通讯不是很合适,一方面是稳定性,另一方面是流量.所以决定写一个WebService,给app提供服务.本文Eclipse+Tomcat+ 以下菜鸟见解. 一.技术选型:刚学的java,所以百度了一通后,发现网上有很多写WebService

从零开始学Java之IO字符流懒人模式(自动生成属性类,方法类,界面类)

平时做一个项目都要建很多的属性类,方法类和View类,学了IO流之后想了一种办法,就是自己写一串代码,然后在文本文档里写class <类名>加上所有的属性,然后运行一下代码就自动生成了一个  <类名>.java   文件.用myeclipse打开就可以了.同样的道理,你写一个只有   class <类名> 的txt文本文档  点一下另一段代码就自动生成了一个方法类,里面带有增删改查四个简单方法的方法类,还有一个View类. 首先说一下,生成属性类的这段代码: packa

从零开始学JavaScript四(数据类型)

一.分类 基本数据类型:undefined.null.string.Boolean.number 复杂数据类型:object object的属性以无序的名称和值对的形式 (name : value) 来定义 1.1 .typeof操作符 鉴于ECMAScript是松散型的,因此需要一种手段来检测给定的变量的数据类型-----typeof就可以负责提供这方面的信息的操作符. 对一个值typeof操作符可能返回下列某个字符串: "undefined"-----------如果这个值未定义