黑马程序员---反射笔记

反射定义:

       反射会造成性能的下降,然后简而言之反射就把相应的类映射成对应的class,然后透过调用java自带的方法可以这个class对象进行相应的操作,能够完整的调用它所有的方法与属性,包换私有的

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

  Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

  有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗 朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。

  一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。

  尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机 制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的 classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、 或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

  Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个 篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其 methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。

J2se1.6提供的API

 

 

字节码定义:

  Bytecode通常指的是已经经过编译,但与特定机器码无关,需要直译器转译后才能成为机器码的中间代码。Bytecode通常不像源码一样可以让人阅读,而是编码后的数值常量、引用、指令等构成的序列。

Bytecode主要为了实现特定软件运行和软件环境、硬件环境无关。Bytecode的实现方式是通过编译器和虚拟机器。编译器将源码编译成Bytecode,特定平台上的虚拟机器将Bytecode转译为可以直接执行的指令。Bytecode的典型应用为Java语言。

获得字符码的方式有三种:

1、  类名.class 例如,System.class

2、  对象.getClass(),例如,new Date().getClass();

3、  Class.forName(“类名”),例如Class.ForName(“java.util.Date”);

java 1.6提供的API信息如下:

方法摘要

 boolean

equals(Object obj)
 将此 Constructor 对象与指定的对象进行比较。

<T extends Annotation>
T

getAnnotation(Class<T> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

 Annotation[]

getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。

 Class<T>

getDeclaringClass()
返回 Class 对象,该对象表示声明由此 Constructor 对象表示的构造方法的类。

 Class<?>[]

getExceptionTypes()
返回一组表示声明要抛出的异常类型的 Class 对象,这些异常是由此 Constructor 对象表示的底层构造方法抛出的。

 Type[]

getGenericExceptionTypes()
返回一组 Type 对象,这些对象表示声明要由此 Constructor 对象抛出的异常。

 Type[]

getGenericParameterTypes()
          按照声明顺序返回一组 Type 对象,这些对象表示此 Constructor 对象所表示的方法的形参类型。

 int

getModifiers()
          以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。

 String

getName()
          以字符串形式返回此构造方法的名称。

 Annotation[][]

getParameterAnnotations()
          按照声明顺序返回一组数组,这些数组表示通过此 Constructor 对象表示的方法的形参上的注释。

 Class<?>[]

getParameterTypes()
          按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。

 TypeVariable<Constructor<T>>[]

getTypeParameters()
          按照声明顺序返回一组 TypeVariable 对象,这些对象表示通过此 GenericDeclaration 对象所表示的一般声明来声明的类型变量。

 int

hashCode()
          返回此 Constructor 的哈希码。

 boolean

isSynthetic()
          如果此构造方法是一个复合构造方法,则返回 true;否则返回 false。

 boolean

isVarArgs()
          如果声明此构造方法可以带可变数量的参数,则返回 true;否则返回 false。

 T

newInstance(Object... initargs)
          使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

 String

toGenericString()
          返回描述此 Constructor 的字符串,其中包括类型参数。

 String

toString()
          返回描述此 Constructor 的字符串。

 

下面的源程序,主要是对反射字段的应用

ReflectTest类:

ReflectTest
 1 package day1;
2 import java.lang.reflect.Field;
3 public class ReflectTest{
4 public static void main(String[] args){
5 String str1="abc";
6 Class cls1=str1.getClass();
7 Class cls2=String.class;
8 //Class cls3=Class.forName("java.lang.String");
9 System.out.println(cls1==cls2);
10 // System.out.println(cls1==cls3);
11 System.out.println(cls1.isPrimitive());
12 System.out.println(int.class.isPrimitive());
13 System.out.println(int.class==Integer.class);
14 System.out.println(int.class==Integer.TYPE);
15 System.out.println(int[].class.isPrimitive());
16 try{
17 //获取相对应的字段
18 ReflectPoint pt1=new ReflectPoint(3,5);
19 Field fieldY=pt1.getClass().getField("y");
20 System.out.println(fieldY.get(pt1));
21 Field fieldx=pt1.getClass().getDeclaredField("x");
22 fieldx.setAccessible(true);
23 System.out.println("a"+fieldx.get(pt1));
24 changeStringValue(pt1);
25 System.out.println(pt1);
26 }catch(Exception e2)
27 {
28 System.out.println(e2);
29 }
30 }
31
32 private static void changeStringValue(Object obj) throws Exception {
33 Field[] fields=obj.getClass().getFields();
34 for(Field field:fields){
35 //field.getType().equals(String.class);
36 if(field.getType()==String.class)
37 {
38 //以后是取出相应的字段,然后用replace方法下替换字符
39 String oldValue=(String)field.get(obj);
40 String newValue=oldValue.replace('b', 'a');
41 field.set(obj, newValue);
42 }
43 }
44
45 }
46
47
48 }



ReflectPoint类:

 1 package day1;
2
3 public class ReflectPoint{
4 private int x;
5 public int y;
6 public String str1="ball";
7 public String str2="basketball";
8 public String str3="itcast";
9 public ReflectPoint(int x, int y) {
10 super();
11 this.x = x;
12 this.y = y;
13 }
14 /* (non-Javadoc)
15 * @see java.lang.Object#toString()
16 */
17 @Override
18 public String toString() {
19 // TODO Auto-generated method stub
20 return str1+":"+str2+":"+str3;
21 }
22
23 }



 

posted @ 2012-02-21 15:01  夜风雪  阅读(460)  评论(2编辑  收藏  举报