• Java反射机制(Reflection)


    Java反射机制(Reflection)

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

    二、反射机制能干什么
      (1)在运行时判断任意一个对象所属的类
      (2)在运行时构造任意一个类的对象
      (3)在运行时判断任意一个类所具有的成员变量和方法
      (4)在运行时调用任意一个对象的方法
      (PS:注意反射机制都是在程序运行时,而不是在编译时。)
      反射机制允许程序在运行时透过JDK提供的反射API获取任意一个已知名称的class的内部消息,包括: 修饰符、父类、接口、属性、构造方法、方法 等所有的信息,并可在程序运行时改变属性的值或者调用方法。

    三、JDK提供的反射机制中的类
      在JDK中主要由以下类来实现Java的反射机制,这些类都位于java.lang.reflect包中(Class类除外):
      java.lang.Class: 代表一个类
      java.lang.reflect.Constructor:代表类的构造方法
      java.lang.reflect.Field:代表类的成员变量
      java.lang.reflect.Method:代表类的方法
      java.lang.reflect.Modifier:代表修饰符
      java.lang.reflect.Array:提供动态创建数组,以及访问数组的元素的静态方法

    四、利用示例对反射机制的使用进行初步体会
    示例一:
    利用反射机制打印java.lang.String类中所有的属性、构造方法、方法

     1 /**
     2  *利用反射机制打印String类中的所方法信息
     3  * @author Administrator
     4  *
     5  */
     6 public class ObjectReflectDemo {    
     7     public static void main(String[] args) throws Exception {
     8         //反射的第一步是获取要操作的类所对应的Class对象
     9         Class<?> cls = Class.forName("java.lang.String");
    10         System.out.println("---------String类中的属性:---------------------");
    11         
    12         Field[] fields = cls.getDeclaredFields();
    13         for(Field f : fields){
    14             System.out.println(f);
    15         }
    16         System.out.println("---------String类中的构造方法:--------------------");
    17         Constructor[] contructors = cls.getDeclaredConstructors();
    18         for(Constructor c : contructors){
    19             System.out.println(c);
    20         }
    21         System.out.println("---------String类中的方法:---------------------");
    22         Method[] methods =  cls.getDeclaredMethods();
    23         for(Method m : methods){
    24             System.out.println(m);
    25         }
    26     }
    27 }

     运行结果:

    ---------String类中的属性:---------------------
    private final char[] java.lang.String.value
    private int java.lang.String.hash
    private static final long java.lang.String.serialVersionUID
    private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields
    public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER
    private static final int java.lang.String.HASHING_SEED
    private transient int java.lang.String.hash32
    ---------String类中的构造方法:--------------------
    public java.lang.String(byte[])
    public java.lang.String(byte[],int,int)
    public java.lang.String(byte[],java.nio.charset.Charset)
    public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
    public java.lang.String(byte[],int,int,java.nio.charset.Charset)
    java.lang.String(int,int,char[])
    java.lang.String(char[],boolean)
    public java.lang.String(java.lang.StringBuilder)
    public java.lang.String(java.lang.StringBuffer)
    public java.lang.String(int[],int,int)
    public java.lang.String(char[],int,int)
    public java.lang.String(char[])
    public java.lang.String(java.lang.String)
    public java.lang.String()
    public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
    public java.lang.String(byte[],int)
    public java.lang.String(byte[],int,int,int)
    ---------String类中的方法:---------------------
    public boolean java.lang.String.equals(java.lang.Object)
    public java.lang.String java.lang.String.toString()
    public int java.lang.String.hashCode()
    public int java.lang.String.compareTo(java.lang.String)
    public int java.lang.String.compareTo(java.lang.Object)
    public int java.lang.String.indexOf(int)
    public int java.lang.String.indexOf(java.lang.String,int)
    public int java.lang.String.indexOf(java.lang.String)
    public int java.lang.String.indexOf(int,int)
    static int java.lang.String.indexOf(char[],int,int,char[],int,int,int)
    public static java.lang.String java.lang.String.valueOf(double)
    public static java.lang.String java.lang.String.valueOf(char[],int,int)
    public static java.lang.String java.lang.String.valueOf(float)
    public static java.lang.String java.lang.String.valueOf(java.lang.Object)
    public static java.lang.String java.lang.String.valueOf(long)
    public static java.lang.String java.lang.String.valueOf(char[])
    public static java.lang.String java.lang.String.valueOf(boolean)
    public static java.lang.String java.lang.String.valueOf(char)
    public static java.lang.String java.lang.String.valueOf(int)
    public char java.lang.String.charAt(int)
    private static void java.lang.String.checkBounds(byte[],int,int)
    public int java.lang.String.codePointAt(int)
    public java.lang.String java.lang.String.concat(java.lang.String)
    public boolean java.lang.String.contains(java.lang.CharSequence)
    public static java.lang.String java.lang.String.copyValueOf(char[])
    public static java.lang.String java.lang.String.copyValueOf(char[],int,int)
    public boolean java.lang.String.endsWith(java.lang.String)
    public static java.lang.String java.lang.String.format(java.util.Locale,java.lang.String,java.lang.Object[])
    public static java.lang.String java.lang.String.format(java.lang.String,java.lang.Object[])
    public byte[] java.lang.String.getBytes()
    public byte[] java.lang.String.getBytes(java.nio.charset.Charset)
    public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException
    public void java.lang.String.getBytes(int,int,byte[],int)
    public void java.lang.String.getChars(int,int,char[],int)
    void java.lang.String.getChars(char[],int)
    public int java.lang.String.codePointBefore(int)
    public int java.lang.String.codePointCount(int,int)
    public int java.lang.String.compareToIgnoreCase(java.lang.String)
    public boolean java.lang.String.contentEquals(java.lang.CharSequence)
    public boolean java.lang.String.contentEquals(java.lang.StringBuffer)
    public boolean java.lang.String.equalsIgnoreCase(java.lang.String)
    private int java.lang.String.indexOfSupplementary(int,int)
    private int java.lang.String.lastIndexOfSupplementary(int,int)
    public int java.lang.String.offsetByCodePoints(int,int)
    int java.lang.String.hash32()
    public native java.lang.String java.lang.String.intern()
    public boolean java.lang.String.isEmpty()
    public int java.lang.String.lastIndexOf(java.lang.String,int)
    static int java.lang.String.lastIndexOf(char[],int,int,char[],int,int,int)
    public int java.lang.String.lastIndexOf(int,int)
    public int java.lang.String.lastIndexOf(int)
    public int java.lang.String.lastIndexOf(java.lang.String)
    public int java.lang.String.length()
    public boolean java.lang.String.matches(java.lang.String)
    public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)
    public java.lang.String java.lang.String.replace(char,char)
    public java.lang.String java.lang.String.replaceAll(java.lang.String,java.lang.String)
    public java.lang.String java.lang.String.replaceFirst(java.lang.String,java.lang.String)
    public java.lang.String[] java.lang.String.split(java.lang.String,int)
    public java.lang.String[] java.lang.String.split(java.lang.String)
    public boolean java.lang.String.startsWith(java.lang.String)
    public boolean java.lang.String.startsWith(java.lang.String,int)
    public java.lang.CharSequence java.lang.String.subSequence(int,int)
    public java.lang.String java.lang.String.substring(int)
    public java.lang.String java.lang.String.substring(int,int)
    public char[] java.lang.String.toCharArray()
    public java.lang.String java.lang.String.toLowerCase(java.util.Locale)
    public java.lang.String java.lang.String.toLowerCase()
    public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
    public java.lang.String java.lang.String.toUpperCase()
    public java.lang.String java.lang.String.trim()
    public boolean java.lang.String.regionMatches(int,java.lang.String,int,int)
    public boolean java.lang.String.regionMatches(boolean,int,java.lang.String,int,int)
    View Code

    从上面示例中可以看出,要想使用反射的第一步就是获取要操作类所对应的Class对象,一共有三种方法:
    第一种: 调用Class类的静态方法forName,比如 Class.forName("java.lang.String")
    第二种: 使用类的.class语法,比如 : Class cls = String.class
    第三种: 调用对象的getClass方法, 比如:String str = "123"; Class cls = str.getClass();(PS:在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型)

     

    示例二:

     1 import java.lang.reflect.Field;
     2 import java.lang.reflect.Method;
     3 
     4 /**
     5  * 要求:
     6  *  1.通过反射的方式调用add方法
     7  *  2.通过反射的方式调用getNum方法
     8  *  3.通过反射的反射修改num属性的值为55,再通过反射的方式调用getNum方法
     9  * @author Administrator
    10  *
    11  */
    12 public class ReflectTest {
    13     private int num = 2;
    14     
    15     public int add(int a,int b){
    16         return a+b;
    17     }
    18     
    19     public int getNum() {
    20         return num;
    21     }
    22 
    23     public static void main(String[] args) throws Exception {
    24         //第一步: 获取ReflectTest类所对应的Class对象
    25         Class<?> cls = Class.forName("ReflectTest");
    26         //第二步:通过Class类的newInstance()方法来创建ReflectTest类的一个对象
    27         Object obj = cls.newInstance();
    28         
    29         //第步:通过Class的getDeclaredMethod(String name, Class<?>... parameterTypes)获取ReflectTest类中指定的方法
    30         Method addMethod = cls.getDeclaredMethod("add", new Class[]{int.class,int.class});
    31         Method getNumMethod = cls.getDeclaredMethod("getNum", new Class[]{});
    32         
    33         //第四部:通过Method类的invoke(Object obj, Object... args)方法来反射调用ReflectTest类中指定的方法
    34         //4.1通过反射调用add方法
    35         int addResult = (int)addMethod.invoke(obj, new Object[]{11,22});
    36         System.out.println("addResult = " + addResult);
    37         
    38         //4.2通过反射的方式调用getNum方法
    39         int returnNum1 = (int)getNumMethod.invoke(obj, new Object[]{});
    40         System.out.println("returnNum1 = " + returnNum1);
    41         
    42         //4.3通过反射的反射修改num属性的值为55,再通过反射的方式调用getNum方法
    43         Field field = cls.getDeclaredField("num");
    44         field.set(obj, 55);
    45         int returnNum2 = (int)getNumMethod.invoke(obj, new Object[]{});
    46         System.out.println("returnNum2 = " + returnNum2);
    47     }
    48 }

    通过上面的2个示例,可以看出:
      (1)反射的第一步是获取要操作的类所对应的Class对象(有三种方式)
      (2)类中每一个方法对应着一个java.lang.reflect.Method对象
      (3)类中每一个属性对应着一个java.lang.reflect.Field对象

    五、使用java反射机制,需要遵循的三步
      第一步:获取要操作的类所对应的Class对象,得到该Class对象后就可以获取想要操作类的所有信息。(具体参考java.lang.Class API)
      第二步: 通过Class对象去获取操作类的属性、构造方法、方法 所分别对应的Field、Constructor、Method的对象
      第三步: 调用Field、Constructor、Method对象中的方法

  • 相关阅读:
    郁闷的Alexa破10万。
    回到杭州,2009开始了。
    美剧。
    英来网招聘:兼职js开发。(补充)
    村姑的Beta 2.0,TT。
    爆牙齿的Web标准面试考题II(iPhone SMS/iChat UI的Web标准实现)
    天使飞来。
    Web标准的未来,浏览器的未来,应用的未来。
    咖啡厅与产品形态。
    学习使用笔和纸。
  • 原文地址:https://www.cnblogs.com/xinhuaxuan/p/6019434.html
Copyright © 2020-2023  润新知