`

JAVA反射机制

 
阅读更多
JAVA反射机制:



通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们.


理论的东东太多也没用,下面我们看看实践 Demo ~



Demo:


[java] view plaincopyprint?
package cn.lee.demo; 
 
import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.lang.reflect.TypeVariable; 
 
public class Main { 
    /**
     * 为了看清楚Java反射部分代码,所有异常我都最后抛出来给虚拟机处理!
     * @param args
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException 
     * @throws IllegalArgumentException 
     * @throws NoSuchFieldException 
     * @throws SecurityException 
     * @throws NoSuchMethodException 
     */ 
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchFieldException, NoSuchMethodException { 
        // TODO Auto-generated method stub 
         
        //Demo1.  通过Java反射机制得到类的包名和类名 
        Demo1(); 
        System.out.println("==============================================="); 
         
        //Demo2.  验证所有的类都是Class类的实例对象 
        Demo2(); 
        System.out.println("==============================================="); 
         
        //Demo3.  通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在],无参构造 
        Demo3(); 
        System.out.println("==============================================="); 
         
        //Demo4:  通过Java反射机制得到一个类的构造函数,并实现构造带参实例对象 
        Demo4(); 
        System.out.println("==============================================="); 
         
        //Demo5:  通过Java反射机制操作成员变量, set 和 get 
        Demo5(); 
        System.out.println("==============================================="); 
         
        //Demo6: 通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等 
        Demo6(); 
        System.out.println("==============================================="); 
         
        //Demo7: 通过Java反射机制调用类中方法 
        Demo7(); 
        System.out.println("==============================================="); 
         
        //Demo8: 通过Java反射机制获得类加载器 
        Demo8(); 
        System.out.println("==============================================="); 
         
    } 
     
    /**
     * Demo1: 通过Java反射机制得到类的包名和类名
     */ 
    public static void Demo1() 
    { 
        Person person = new Person(); 
        System.out.println("Demo1: 包名: " + person.getClass().getPackage().getName() + ","  
                + "完整类名: " + person.getClass().getName()); 
    } 
     
    /**
     * Demo2: 验证所有的类都是Class类的实例对象
     * @throws ClassNotFoundException 
     */ 
    public static void Demo2() throws ClassNotFoundException 
    { 
        //定义两个类型都未知的Class , 设置初值为null, 看看如何给它们赋值成Person类 
        Class<?> class1 = null; 
        Class<?> class2 = null; 
         
        //写法1, 可能抛出 ClassNotFoundException [多用这个写法] 
        class1 = Class.forName("cn.lee.demo.Person"); 
        System.out.println("Demo2:(写法1) 包名: " + class1.getPackage().getName() + ","  
                + "完整类名: " + class1.getName()); 
         
        //写法2 
        class2 = Person.class; 
        System.out.println("Demo2:(写法2) 包名: " + class2.getPackage().getName() + ","  
                + "完整类名: " + class2.getName()); 
    } 
     
    /**
     * Demo3: 通过Java反射机制,用Class 创建类对象[这也就是反射存在的意义所在]
     * @throws ClassNotFoundException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     */ 
    public static void Demo3() throws ClassNotFoundException, InstantiationException, IllegalAccessException 
    { 
        Class<?> class1 = null; 
        class1 = Class.forName("cn.lee.demo.Person"); 
        //由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数哈~ 
        Person person = (Person) class1.newInstance(); 
        person.setAge(20); 
        person.setName("LeeFeng"); 
        System.out.println("Demo3: " + person.getName() + " : " + person.getAge()); 
    } 
     
    /**
     * Demo4: 通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象
     * @throws ClassNotFoundException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     * @throws IllegalArgumentException 
     */ 
    public static void Demo4() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException 
    { 
        Class<?> class1 = null; 
        Person person1 = null; 
        Person person2 = null; 
         
        class1 = Class.forName("cn.lee.demo.Person"); 
        //得到一系列构造函数集合 
        Constructor<?>[] constructors = class1.getConstructors(); 
         
        person1 = (Person) constructors[0].newInstance(); 
        person1.setAge(30); 
        person1.setName("leeFeng"); 
         
        person2 = (Person) constructors[1].newInstance(20,"leeFeng"); 
         
        System.out.println("Demo4: " + person1.getName() + " : " + person1.getAge() 
                + "  ,   " + person2.getName() + " : " + person2.getAge() 
                ); 
         
    } 
     
    /**
     * Demo5: 通过Java反射机制操作成员变量, set 和 get
     * 
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     * @throws NoSuchFieldException 
     * @throws SecurityException 
     * @throws InstantiationException 
     * @throws ClassNotFoundException 
     */ 
    public static void Demo5() throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, InstantiationException, ClassNotFoundException 
    { 
        Class<?> class1 = null; 
        class1 = Class.forName("cn.lee.demo.Person"); 
        Object obj = class1.newInstance(); 
         
        Field personNameField = class1.getDeclaredField("name"); 
        personNameField.setAccessible(true); 
        personNameField.set(obj, "胖虎先森"); 
         
         
        System.out.println("Demo5: 修改属性之后得到属性变量的值:" + personNameField.get(obj)); 
         
    } 
     
 
    /**
     * Demo6: 通过Java反射机制得到类的一些属性: 继承的接口,父类,函数信息,成员信息,类型等
     * @throws ClassNotFoundException 
     */ 
    public static void Demo6() throws ClassNotFoundException 
    { 
        Class<?> class1 = null; 
        class1 = Class.forName("cn.lee.demo.SuperMan"); 
         
        //取得父类名称 
        Class<?>  superClass = class1.getSuperclass(); 
        System.out.println("Demo6:  SuperMan类的父类名: " + superClass.getName()); 
         
        System.out.println("==============================================="); 
         
         
        Field[] fields = class1.getDeclaredFields(); 
        for (int i = 0; i < fields.length; i++) { 
            System.out.println("类中的成员: " + fields[i]); 
        } 
        System.out.println("==============================================="); 
         
         
        //取得类方法 
        Method[] methods = class1.getDeclaredMethods(); 
        for (int i = 0; i < methods.length; i++) { 
            System.out.println("Demo6,取得SuperMan类的方法:"); 
            System.out.println("函数名:" + methods[i].getName()); 
            System.out.println("函数返回类型:" + methods[i].getReturnType()); 
            System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers())); 
            System.out.println("函数代码写法: " + methods[i]); 
        } 
         
        System.out.println("==============================================="); 
         
        //取得类实现的接口,因为接口类也属于Class,所以得到接口中的方法也是一样的方法得到哈 
        Class<?> interfaces[] = class1.getInterfaces(); 
        for (int i = 0; i < interfaces.length; i++) { 
            System.out.println("实现的接口类名: " + interfaces[i].getName() ); 
        } 
         
    } 
     
    /**
     * Demo7: 通过Java反射机制调用类方法
     * @throws ClassNotFoundException 
     * @throws NoSuchMethodException 
     * @throws SecurityException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     * @throws InstantiationException 
     */ 
    public static void Demo7() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException 
    { 
        Class<?> class1 = null; 
        class1 = Class.forName("cn.lee.demo.SuperMan"); 
         
        System.out.println("Demo7: \n调用无参方法fly():"); 
        Method method = class1.getMethod("fly"); 
        method.invoke(class1.newInstance()); 
         
        System.out.println("调用有参方法walk(int m):"); 
        method = class1.getMethod("walk",int.class); 
        method.invoke(class1.newInstance(),100); 
    } 
     
    /**
     * Demo8: 通过Java反射机制得到类加载器信息
     * 
     * 在java中有三种类类加载器。[这段资料网上截取]

        1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。

        2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类

        3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
     * 
     * @throws ClassNotFoundException 
     */ 
    public static void Demo8() throws ClassNotFoundException 
    { 
        Class<?> class1 = null; 
        class1 = Class.forName("cn.lee.demo.SuperMan"); 
        String nameString = class1.getClassLoader().getClass().getName(); 
         
        System.out.println("Demo8: 类加载器类名: " + nameString); 
    } 
     
     
     

/**

* @author xiaoyaomeng
*
*/ 
class  Person{ 
    private int age; 
    private String name; 
    public Person(){ 
         
    } 
    public Person(int age, String name){ 
        this.age = age; 
        this.name = name; 
    } 
 
    public int getAge() { 
        return age; 
    } 
    public void setAge(int age) { 
        this.age = age; 
    } 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 

 
class SuperMan extends Person implements ActionInterface 

    private boolean BlueBriefs; 
     
    public void fly() 
    { 
        System.out.println("超人会飞耶~~"); 
    } 
     
    public boolean isBlueBriefs() { 
        return BlueBriefs; 
    } 
    public void setBlueBriefs(boolean blueBriefs) { 
        BlueBriefs = blueBriefs; 
    } 
 
    @Override 
    public void walk(int m) { 
        // TODO Auto-generated method stub 
        System.out.println("超人会走耶~~走了" + m + "米就走不动了!"); 
    } 

interface ActionInterface{ 
    public void walk(int m); 





个人觉得使用反射机制的一些地方:


1.工厂模式:Factory类中用反射的话,添加了一个新的类之后,就不需要再修改工厂类Factory了
2.数据库JDBC中通过Class.forName(Driver).来获得数据库连接驱动
3.分析类文件:毕竟能得到类中的方法等等
4.访问一些不能访问的变量或属性:破解别人代码

====
反射的好处:
1.扩展性 耦合低 灵活度高

坏处:
1.效率和安全性 以及代码维护检查

使用场景:
1.各种框架上

提高反射的效率请看:setAccessible(true)设置为true 关闭访问的安全检查。

AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。



在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。



setAccessible

public void setAccessible(boolean flag)

                   throws SecurityException

将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。



实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问



由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
分享到:
评论

相关推荐

    java反射机制.zip

    java反射机制java反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制.zipjava反射机制...

    java反射机制

    Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者能够在运行时动态地获取类的信息(如类名、方法名、参数类型)并调用方法,创建对象,甚至...

    JAVA反射机制应用

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

    Java反射机制的实现_Reflection

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过Java反射机制,开发者可以在不知道具体类名的情况下创建对象,调用方法,访问和修改私有成员变量,以及...

    一个例子让你了解Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中在java.lang.reflect包下,包括Class、Constructor、Method和...

    java 反射机制

    ### Java反射机制深入理解 #### 一、反射机制概述 Java反射机制是一种强大的工具,它允许程序在运行时检查和操作任何类、方法、构造函数和字段等元素。这种能力对于构建灵活的应用程序和框架非常有用,特别是那些...

    JAVA反射机制的简单理解

    Java反射机制是Java语言提供的一种强大工具,它允许在程序运行时动态地获取类的信息以及对类的对象进行操作。在Java中,静态编译时类型检查确保了代码的稳定性,但有时我们需要在运行时根据需求动态地创建对象、调用...

    Java 反射机制 代码的实例

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地获取类的信息并调用其方法,创建对象,访问私有成员,甚至改变类的行为。在深入...

    候捷谈Java反射机制

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取和操作任何已知名称的类的内部信息。这一机制使得Java具备了一定的动态性,虽然在传统的分类中Java被视为静态类型语言。通过反射,开发者可以在...

    java 反射机制详解

    Java 反射机制是 Java 语言中的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、属性、方法等)并调用对象的方法,甚至修改对象的状态。这一机制极大地增强了 Java 程序的灵活性和可扩展性,尤其是在...

    Java反射机制学习(二)

    这篇博文"Java反射机制学习(二)"可能深入探讨了如何利用反射进行动态类型处理、访问私有成员以及创建对象等核心概念。在这里,我们将详细讨论Java反射的基本用法及其在实际开发中的应用。 1. **什么是反射**: ...

    java反射机制和动态代理的原理

    java反射机制和动态代理的原理,熟悉反射机制和动态代理

    Java反射机制 Java反射机制

    ### Java反射机制详解 #### 一、Java反射机制概述 Java反射机制是Java语言的一个重要特性,它允许程序在运行时获取类的信息并操作对象。Java反射机制的主要作用包括:获取类的所有属性和方法、构造动态实例、调用...

    Java反射机制课件ppt

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并操作类的对象。这种机制使得Java具有高度的灵活性和动态性,可以在编译时未知类的情况下进行类的加载、实例化、方法调用等操作...

    java反射机制工具类

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息。这个特性使得Java具备了高度的灵活性,能够在运行时动态地发现和使用类的属性和方法,即使这些信息在编译时...

    java反射机制,很安逸.不要错过

    Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查并操作类、接口、字段和方法的信息,打破了通常编译时静态绑定的限制。通过反射,我们可以动态地创建对象,调用方法,访问和修改字段值,甚至...

    java反射机制核心代码

    java反射机制核心代码,小弟一直弄不明白,怎么通过反射来调用私有成员方法,看了这个后,你可以随心调用private方法,和属性,记得添加setAccessable(true),哦,要不还是不行,如:method.setAccessable(true);

    Java反射机制总结(实例分析)

    Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时动态地获取类的信息并进行操作。通过反射,开发者可以在程序执行时发现并访问类的字段(fields)、方法(methods)以及构造器(constructors),...

Global site tag (gtag.js) - Google Analytics