往往当我们面对一项新的知识时,我们往往需要知道三个方面,它是什么,它能做什么,它比原有知识强在哪里,我们该怎么使用它。当你能够解决这些问题时,便意味着你已经对这项知识入门了。

一、是什么

  Java Reflaction in Action有这么一句话,可以解释。反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就是反射可以在运行时根据指定的类名获得类的信息。

二、为什么

  我们为什么要使用反射,它的作用是什么,它在实际的编程中有什么应用。

  首先我们先明确两个概念,静态编译和动态编译。

  静态编译:在编译时确定类型,绑定对象,即通过。 
  动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多    
  态的应用,有以降低类之间的藕合性。

  我们可以明确的看出动态编译的好处,而反射就是运用了动态编译创建对象。

  那么我们再来看看实际中反射又有什么好处那?

  往往对比能更加直观的向我们展示两者的不同。

  先从某个代码案例上来解释(套用一篇博文的一个例子:http://blog.csdn.net/justdoit_potato/article/details/51011843)

  若是不用反射,它是这样的

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 fruitName){  
        fruit f=null;  
        if("Apple".equals(fruitName)){  
            f=new Apple();  
        }  
        if("Orange".equals(fruitName)){  
            f=new Orange();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Orange");  
        f.eat();  
    }  
   
}  

  可以发现,每当我们要添加一种新的水果的时候,我们将不得不改变Factory中的源码,而往往改变原有正确代码是一种十分危险的行为。而且随着水果种类的增加,你会发现你的factory类会越来越臃肿,

不得不说这是一种十分--的做法。(初学者可能会问,我们为什么不直接在main方法中new水果那,我们可能会需要getInstance方法做一些别的事情。。。所以不直接new);

而反射无疑是一种聪明的办法,看代码。

  

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;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Reflect.Apple");  
        if(f!=null){  
            f.eat();  
        }  
    }  
}  

  在出现新品种水果的时候,你完全不用去修改原有代码。

  从上面的案例中,我们可以清楚的体会到反射的优越性。

  那么有的人又会问,这个例子能完全明白,但是如果放到实际的编程,应用中,我们又会在什么情况下用到反射那?

  举一个看到过的例子,在实际开发中,我们需要把一个包中的class new出来,但是这个包中的类总是需要变动,那么怎么办,难道总是修改main方法中xxx=new xxx()吗。这样无疑是麻烦的。而运用反射。我们可以相应的增加一个配置文件,在里面记录包中所有的类名,包中类增加时就加一个类名,删除时就删除一个类名。让main方法去读取这个配置文件中的类名,通过反射获得实例,完全不用我们去修改main方法中的代码。

  反射还有什么用那?他甚至可以修改其他类中的私有属性。android开发中,我们需要改变一个私有标志位的时候,android源码并没有提供set方法,我们又不能改变源码,怎么办,反射可以完美解决这个问题。

  说了这么多,那么我们的开发中,为什么不全部都用反射那?一个原因,开销,它的开销是什么昂贵的,随意尽量在最需要的地方使用反射。

三、怎么用

  说完是什么,为什么,我们必然需要掌握如何使用反射,先看反射中涉及了那些方法。

  Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo;
    Object obj=c.newInstance();//创建对象的实例
    OK,有了对象就什么都好办了,想要什么信息就有什么信息了。  
    获得构造函数的方法
    Constructor getConstructor(Class[] params)//根据指定参数获得public构造器

Constructor[] getConstructors()//获得public的所有构造器

Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器

Constructor[] getDeclaredConstructors()//获得public的所有构造器
    获得类方法的方法
    Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法

Method[] getMethods()//获得所有的public方法

Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法

Method[] getDeclaredMethods()//获得所以的public和非public方法
    获得类中属性的方法
    Field getField(String name)//根据变量名得到相应的public变量

Field[] getFields()//获得类中所以public的方法

Field getDeclaredField(String name)//根据方法名获得public和非public变量

Field[] getDeclaredFields()//获得类中所有的public和非public方法

  看到这些方法,你就可以明白,反射是多么的强大了,当你正确使用这些方法的时候,基本上是掌握了反射的技巧。

  参考博文:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html

  

Java反射机制--是什么,为什么,怎么用。的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  4. java基础知识(十一)java反射机制(下)

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

  5. Java反射机制专题

    ·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...

  6. java反射机制深入详解

    java反射机制深入详解  转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...

  7. Java反射机制DOME

    Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...

  8. 反射——Java反射机制

    反射概述 什么是反射? ①   反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ②   JAVA反射机制是在运行状态中,对应任意一个类,都能 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  10. Java反射机制学习与研究

    Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...

随机推荐

  1. 前端学习之路之CSS (一)

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 简介:    CSS 指层叠样式表 (Cascading Style Sheets)    样式定义如何显示 HT ...

  2. C# Winform中的ComboBox控件绑定数据库项目作为列表内容

    //初始化院区下拉列表,使用了Oracle数据库中的表项目 try { //string connString = "User=system;Password=manager;Data So ...

  3. DLL调用的两种方式(IDE:VC6.0,C++)

    原文:http://www.cnblogs.com/Pickuper/articles/2050409.html DLL调用有两种方式,一种是静态调用,另外一种是动态调用 (一)静态调用 静态调用是一 ...

  4. 排序算法积累(2)----sort排序

    转载:http://blog.csdn.net/sunshangjin/article/details/40296357 想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数so ...

  5. 从尾到头打印链表(C++和Python 实现)

    (说明:本博客中的题目.题目详细说明及参考代码均摘自 “何海涛<剑指Offer:名企面试官精讲典型编程题>2012年”) 题目 输入一个链表的头结点, 从尾到头反过来打印出每个结点的值. ...

  6. Nginx 性能参数优化

    user www www; # ginx要开启的进程数 一般等于cpu的总核数,没必要开那么多,1个nginx内存消耗10兆左右 worker_processes 4; # 为每个进程分配cpu,上例 ...

  7. Redis源码学习1-sds.c

    https://github.com/huangz1990/redis-3.0-annotated/blob/unstable/src/sds.c#L120 /* SDSLib, A C dynami ...

  8. 关于派生类访问基类对象的保护变量的问题 --Coursera

    https://class.coursera.org/pkupop-001/forum/thread?thread_id=350   郭天魁· 6 months ago 在课件中我们知道如下程序是不能 ...

  9. MySQL案例之Timestamp和Datetime

    mysql数据库常用的时间类型有timestamp和datetime,两者主要区别是占用存储空间长度不一致.可存储的时间也有限制,但针对不同版本下,timestamp字段类型的设置需要慎重,因为不注意 ...

  10. 教你如何封装异步网络连接NSURLConnection实现带有百分比的下载

    教你如何封装异步网络连接NSURLConnection实现带有百分比的下载 注:本教程需要你对block有着较为深刻的理解,且对如何封装对象有着一些经验. 也许你已经用惯了AFNetworking2. ...