黑马程序员——反射

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

什么是反射?

反射就是把java类中的各种成分映射成相应的java类。

反射的基石——>Class

一个Java类用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机、变速箱等等也是一个个的类。表示Java类的Class类显然要提供一系列的方法,来获取其中的变量、方法、构造方法、修饰符、包等信息。这些信息就是用相应类的实例对象来表示,它们是File、Method、Contrutor、Package等等。

学习反射的要点

一个类中的每个成员都可以用相应的API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象

Constructor类  构造方法反射的应用

Constructor类代表某个类的构造方法

得到某个类的所有构造方法

Constructor counstructors[] = Class.forName("java.lang.String").getConstructors();

得到某一个构造方法

Constructor counstructor = Class.forName("java.lang.String").getConstructors(StringBuffer.class);

创建实例对象

通常方式:String str = new String(new StringBuffer("abc"));

反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));

调用获得的方法时,要用到上面相同类型的实例对象

String obj = (String)Class.forName("java.lang.String").newInstance();

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

Class------->constructor-------------->new Object

由Class得到构造方法,由构造方法创建实例对象。

 

Field类   成员变量的反射

Field类代表某个类中的一个成员变量

暴力反射、以及将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的b改成a  实例如下:

public class ReflectPoint {
 private int x = 0;
 public int y = 0;
 public String str1 = "abc";
 public String str2 = "basketball";
 public String str3 = "bai";
 public ReflectPoint(int x, int y) {
  super();
  this.x = x;
  this.y = y;
 }
 public String toString(){
  return str1+":"+str2+":"+str3;
  
 }
 public int hashCoed(){
  final int prime = 31;
  int result = 1;
  result = prime * result + x;
  result = prime * result + y;
  
  return result;
  
 }
}

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class ReflectTest {
 public static void main(String[] args) throws Exception{
  ReflectPoint p1 = new ReflectPoint(3,7);
  Field fieldY = p1.getClass().getField("y");
  System.out.println(fieldY.get(p1));
  //暴力反射
  Field fieldX = p1.getClass().getDeclaredField("x");
  fieldX.setAccessible(true);
  System.out.println(fieldX.get(p1));
  
  changeStringValue(p1);
  System.out.println(p1);
 }

 private static void changeStringValue(Object obj) throws IllegalAccessException {
  Field[] fields = obj.getClass().getFields();
  for (int i = 0; i < fields.length; i++) {
   if(fields[i].getType()== String.class){
    String oldValue = (String)fields[i].get(obj);
    String newValue = oldValue.replace('b', 'a');
    fields[i].set(obj, newValue);
   }
  }
 }

 

Method类  成员方法的反射

得到类中的某一个方法:

Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);

调用方法:

通常方式:System.out.println(str.charAt(1));

反射方式:System.out.println(charAt.invoke(str,1);

注意:如果传递给Method对象的invoke()方法的一个参数为null,这有什么样的意义?

说明Method对象对应的是一个静态方法。

JDK1.4和JDK1.5的invoke方法的区别

jdk1.5:public Object invoke(Object obj,Object...  args)

jdk1.4:public Object invoke(Object obj,Object[]   args)

按jdk1.4的语法需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别应对被调用方法中的一个参数,所以,调用CharAt方法的代码也可以用jdk1.4改写为charAt.invoke("str",new Object[]{1})形式。

 

用反射方式执行某个类的main方法

写一个程序,这个程序能够根据用户名提供的类名,去执行该类中的main方法。

普通方式调用:Arguments.main(new String[]{"23","233"});

反射方式调用:Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
                         mainMethod.invoke(null, (Object)new String[]{"aa","bb","cc"});
                         mainMethod.invoke(null, new Object[]{new String[]{"aa","bb","cc"}});编译器会做特殊处理,编译时不把参数当作数组看待,也就是不会把数组打散成若干个参数了。

 

数组的反射

什么样的数组是同一个Class

具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。

代表数组的Class实例对象的getSuperClass方法返回的父类为Object类对应的class.

 

Arrays.asList()方法处理int[]和String[]时的差异

只能处理String[] 不能处理int[]

Araay工具类用于完成对数组的反射操作,它没有办法得到数组的类型,但可以得到元素的类型。

 

 

----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

详情请查看:http://edu.csdn.net/heima

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值