现在的位置: 首页 > 综合 > 正文

java反射用法

2013年10月21日 ⁄ 综合 ⁄ 共 2988字 ⁄ 字号 评论关闭

反射这块东西可能是刚刚接触,看的有点云山雾罩的,看了几遍,写个日志,原理部分略过,先看用法,回头咱再看原理

1:构造方法的反射
可以用于创造对象。
可以反射出对象的构造方法
class Constroct
{
public static void main(String [] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Constructor c = String.class.getConstructor(StringBuffer.class);
String str = (String) c.newInstance(new StringBuffer("hello"));
System.out.println(str.charAt(2));
}
}

2:成员变量的反射
我们定义一个类先
public class ReflectPoint 
{
private int x;
public int y;

public String str1 = "hellojava";
public String str2 = "jakdbbbbbizad";
public String str3 = "hahahaha";

public ReflectPoint(int x, int y) 
{
super();
this.x = x;
this.y = y;
}

public String toString()
{
return str1+" : "+str2+" : "+str3;
}

假设我们有这样的一个类,我们假设这个类是别人写的。

field:
class Constroct
{
public static void main(String [] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException
{
ReflectPoint n = new ReflectPoint(3,5);//新建一个类,这个类是我们之前定义的
Field Y = n.getClass().getField("y");//反射我们类里面的y参数(public的)
System.out.println(Y.get(n));
System.out.println(n.y);

Field X = n.getClass().getDeclaredField("x");//反射我们类里面的x参数,注意x是private的
X.setAccessible(true);//强制反射,对于private 的参数,我们需要去强制访问它
System.out.println(X.get(n));

}
}

看一个题目:
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。

//反射综合栗子
class Constroct
{
public static void main(String [] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException
{

ReflectPoint n = new ReflectPoint(3,5);

ChangeStringValue(n);
System.out.println(n);
}

private static void ChangeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field [] fields = obj.getClass().getFields(); //将对象中的元素都反射到一个数组里
for(Field field:fields) //遍历所有对象
{
//字节码比较用 == 号
if(field.getType() == String.class)// 判断是否为字符串
{
String oldvalue = (String)field.get(obj); //获取对象反射到的那个值 
String newvalue = oldvalue.replace('a', 'b');//替换
field.set(obj,newvalue);//设置新的值
}
}
}
}

method类:

写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
首先我们看,main()方法其实说白了,它也是方法,方法就也有参数 我们可以看到main()方法的参数是String[] args 是个数组,呵呵。学过c的可以明白,我们这里相当于给main()方法传了个数组首地址,数组里面怎么放,看我们怎么用。
但是可以看到,我们这里可以直接调用那个类的main()方法的,可是为什么还要多此一举呢,我们调用的时候并不知道是哪个类,可以通过参数来确定调用哪个类的main()方法。

class Constroct
{
public static void main(String [] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException, ClassNotFoundException
{

String s =args[0];
Method mainMethod = Class.forName(s).getMethod("main", String[].class);//反射调用main()方法
/*
下面是数组反射的两种调用方法,2选1.简单的说下,因为数组作为参数传进去的时候在1.4版本会将数组拆包,所以在传进去的数组,
它会当作多个参数去处理。我们第一个处理办法是对数据进行装包,拆包后是个数组。第二中方法是将数据强转成Object对象,然后拆
包的时候将Object拆开,发现是个数组就可以用了,哈哈哈。
*/
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke(null,(Object){new String[]{"111","222","333"}});

}
}
}

class TestArguments
{
public static void main(String[] args)
{
for(String str:args)
{
System.out.println(str);
}
}
}

这里的栗子代码读没有几行,但是理解起来相当费劲。需要好好理解

抱歉!评论已关闭.