java反射机制与具体使用方法
2017-05-12 18:47
375 查看
一、认识反射机制
答:java是一门是动态的语言,可以适应于变化的环境,比如,Java中的类是根据需要载入的。反射机制就是java“动态性”的重要体现,是java的一个重要特点,主要用于JavaEE的框架之中。它允许在运行状态中,通过某一具体的类,便可以得知该类的所有属性和方法,通过仁义类的实例,便可以调用它的任意方法和属性。
二、实例化Class对象
答:先简单认识一下反射:在正常情况下,程序中类的实例是在类已经定义好的基础上生成的,但是在反射机制中, 可以打破这一概念。反射中所谓的“反”就是可以通过实例找到该实例的出处。
我们知道,java中所有的类都是Object类的子类,而在Object类中有一个名为getClass()的方法,利用这个方法就可以获得一个实例的所属类,该方法定义如下:
在java.lang包下有一个反射的源头类,名为Class,Class 类的实例表示正在运行的 Java 应用程序中的类和接口。该类有三种实例化方法,
一是上面介绍的getClass()方法,该方法是通过实例调用的。
二是通过类名称的class属性取得,在框架中(hibernate、mybatis、spring)经常使用,比如
三是通过Class类的一个名为forName(String fullname)可以获得,和上面两种方法相比,该方法无需导入需要的包,String类型的参数是类的全路径名称。
三、反射实例化对象
在正常情况下,我们可以根据已有的类,然后new出其实例,但是反射机制支持一种别样的生成实例的方法。在java.lang.Class类中有一个newInstance()方法,通过该方法可以创建此 Class 对象所表示的类的一个新实例,比如:
程序的输出结果如下:
—–这是无参构造函数———–
class com.andy.temp.Cat
this is a cat
读到这里,是不是会感觉反射的做法比较多余,明明可以用一个new可以解决的问题为什么要写两行代码来取代呢?这是因为在开发中,new是造成耦合的主要元凶。具体例子如下:
让我们回忆一下工厂模式中的简单工厂(静态工厂),代码如下:
简单工厂有很多局限,每增加一个类就要修改工厂类,那么如果随时都有可能增加新的类,工厂类也会一直进行更改。以上都是通过new进行实例化的,而new就成了问题的关键点。现在通过反射来弥补以上bug。
主要修改了MyFactory类,使其使用反射机制根据传入的参数动态的生成实例,此时增加类时,就不需要再更改MyFactory类了,注意在主函数调用时,传入的是全类名。
下一篇:《用反射机制调用构造函数》
答:java是一门是动态的语言,可以适应于变化的环境,比如,Java中的类是根据需要载入的。反射机制就是java“动态性”的重要体现,是java的一个重要特点,主要用于JavaEE的框架之中。它允许在运行状态中,通过某一具体的类,便可以得知该类的所有属性和方法,通过仁义类的实例,便可以调用它的任意方法和属性。
二、实例化Class对象
答:先简单认识一下反射:在正常情况下,程序中类的实例是在类已经定义好的基础上生成的,但是在反射机制中, 可以打破这一概念。反射中所谓的“反”就是可以通过实例找到该实例的出处。
我们知道,java中所有的类都是Object类的子类,而在Object类中有一个名为getClass()的方法,利用这个方法就可以获得一个实例的所属类,该方法定义如下:
public final Class<?> getClass()。 例1、 Date myDate=new Date(); System.out.println(myDate.getClass()); 以上代码将会输出:class java.util.Date 即myDate的所属类的全类名,此时就可以通过反射机制中的方法去访问其全部信息(包括函数和字段)
在java.lang包下有一个反射的源头类,名为Class,Class 类的实例表示正在运行的 Java 应用程序中的类和接口。该类有三种实例化方法,
一是上面介绍的getClass()方法,该方法是通过实例调用的。
Date myDate=new Date(); Class<?>class1=myDate.getClass();
二是通过类名称的class属性取得,在框架中(hibernate、mybatis、spring)经常使用,比如
Class<?>class1=Date.class;
三是通过Class类的一个名为forName(String fullname)可以获得,和上面两种方法相比,该方法无需导入需要的包,String类型的参数是类的全路径名称。
Class<?>class1=Class.forName("java.util.Date");
三、反射实例化对象
在正常情况下,我们可以根据已有的类,然后new出其实例,但是反射机制支持一种别样的生成实例的方法。在java.lang.Class类中有一个newInstance()方法,通过该方法可以创建此 Class 对象所表示的类的一个新实例,比如:
package com.andy.temp; class Cat{ public Cat() { System.out.println("-----这是无参构造函数-----------"); } @Override public String toString() { return "this is a cat"; } } public class Temp { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class<?>class1=Class.forName("com.andy.temp.Cat"); Object cat=class1.newInstance();//相当于正常情况下的new,会调用构造函数 System.out.println(class1);//输出“class com.andy.temp.Cat” System.out.println(cat);//调用toString方法 } }
程序的输出结果如下:
—–这是无参构造函数———–
class com.andy.temp.Cat
this is a cat
读到这里,是不是会感觉反射的做法比较多余,明明可以用一个new可以解决的问题为什么要写两行代码来取代呢?这是因为在开发中,new是造成耦合的主要元凶。具体例子如下:
让我们回忆一下工厂模式中的简单工厂(静态工厂),代码如下:
package com.andy.test; interface Fruit{ public void eat() ; } class Apple implements Fruit{ @Override public void eat() { System.out.println("eat apples"); } } class Orange implements Fruit{ @Override public void eat() { System.out.println("eat oranges"); } } class MyFactory { public static Fruit getInstance(String calssName) { if ("apple".equals(calssName)) { return new Apple(); } else if ("orange".equals(calssName)) { return new Orange(); } else return null; } } public class Factory { public static void main(String[] args) { Fruit fruit=MyFactory.getInstance("apple"); fruit.eat(); } }
简单工厂有很多局限,每增加一个类就要修改工厂类,那么如果随时都有可能增加新的类,工厂类也会一直进行更改。以上都是通过new进行实例化的,而new就成了问题的关键点。现在通过反射来弥补以上bug。
package com.andy.test; interface Fruit{ public void eat() ; } class Apple implements Fruit{ @Override public void eat() { System.out.println("eat apples"); } } class Orange implements Fruit{ @Override public void eat() { System.out.println("eat oranges"); } } class MyFactory { public static Fruit getInstance(String calssName) { Fruit fruit=null; try { fruit =(Fruit)Class.forName(calssName).newInstance(); } catch (Exception e) { e.printStackTrace(); } return fruit; } } public class Factory { public static void main(String[] args) { Fruit fruit=MyFactory.getInstance("com.andy.test.Orange"); fruit.eat(); } }
主要修改了MyFactory类,使其使用反射机制根据传入的参数动态的生成实例,此时增加类时,就不需要再更改MyFactory类了,注意在主函数调用时,传入的是全类名。
下一篇:《用反射机制调用构造函数》
相关文章推荐
- WAS的具体设置和使用方法(转)
- Jakarta Commons Digester 简介和具体使用方法
- 存储过程中使用RETURN语句返回数值,.Net里用ExecuteScalar方法结果将会导致一个未引用到具体对象的异常
- Jakarta Commons Digester 简介和具体使用方法
- 将对setjmp与longjmp的具体使用方法和适用的场合,进行一个非常全面的阐述。
- Jakarta Commons Digester 简介和具体使用方法
- 使用Java反射机制实现访问其他类的私有方法
- SSH pager-taglib分页的实现 具体使用方法 分页pager
- 关于使用SurfaceFligner进行绘图的具体实现方法
- java7新特性 当使用可变并且非具体类型形式化参数的方法时候,改进警告与报错的提示
- VB中资源文件的具体使用方法
- matlab中随机函数的具体使用方法
- 使用Java反射机制实现访问类中的私有变量或者方法
- SSH pager-taglib分页的实现 具体使用方法 分页pager
- 数据字典(选项)管理 的具体使用方法介绍 - 以审批流程类别管理为例(工作流类型管理)
- WAS的具体设置和使用方法(转)
- safearray 的具体使用方法
- RegisterHotKey的具体使用方法
- [转]关于使用SurfaceFligner进行绘图的具体实现方法
- 使用Java反射机制实现访问其他类的私有方法