反射Reflect

<p>
<br />

</p>
<h2>
<span style="font-family:Tahoma,Microsoft Yahei,Simsun; font-size:32px; color:#444444"><span style="line-height:21px">定义与解释</span></span>
</h2>
<p>
<br />

</p>
<p>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px">&nbsp; &nbsp;反射就是把Java为中的各种成分映射成相应的Java类,例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类表表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类,表示Java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。<br />
&nbsp; 一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射的要点。<br />
<br />
<br />
</span>
</p>
<h2>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; line-height:21px"><span style="font-size:32px">Constructor类</span></span>
</h2>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">------------------------------------------------------------------------------------------------------------------------------------------</span><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"></span></span></span></span><br />
一:Constructor类代表某个类中的一个构造方法<br />
二:得到某个类所有的构造方法:<br />
&nbsp; &nbsp;例子:Constructor[] &nbsp;constructors = Class.forName(&quot;java.lang.String&quot;).getConstructors();<br />
三:得到某一个构造方法:<br />
&nbsp; &nbsp;例子:Constructor constructor = Class.forName(&quot;java.lang.String&quot;).getConstructor<br />
<br />
<br />
(StringBuffer.class);<br />
&nbsp; &nbsp;获得方法时要用到类型<br />
四:创建实例对象:<br />
&nbsp; &nbsp;通常方式:String str = new String(new StringBuffer(&quot;abc&quot;);<br />
&nbsp; &nbsp;反射方式:String str = (String)constructor.newInstance(new StringBuffer(&quot;abc&quot;));<br />
&nbsp; &nbsp;调用获得的方法时要用到上面相同类型的实例对象<br />
五:Class.newInstance()方法:<br />
&nbsp; &nbsp;例子:String obj = (String)Class.forName(&quot;java.lang.String&quot;).newInstance();<br />
&nbsp; &nbsp;该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。<br />
&nbsp; &nbsp;该方法内部的具体代码是怎样写得呢?用到了缓存机制来保存默认构造方法的实例对象<br />
<br />
<br />
</span>
<h2>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; line-height:21px"><span style="font-size:32px">Field类</span></span>
</h2>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">------------------------------------------------------------------------------------------------------------------------------------------</span><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"></span></span></span><br />
一:Field类代表某个类中的一个成员变量<br />
二:用Eclipse自动生成Java类的构造方法《Alt + Shift + s》(Generate Constructor using &nbsp;Fields...)<br />
&nbsp; &nbsp; 问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,而该类的实例对象有多个,如果是与对象关联,那关联的是哪个对象呢?所以字段fieldX代表的是X的定义,而&nbsp; 不是具体的X变量。<br />
三:作业:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的b改成a<br />
</span>
<p>
</p>
<h2>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; line-height:21px"><span style="font-size:32px">示例</span></span>
</h2>
<p>
<span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px">------------------------------------------------------------------------------------------------------------------------------------------</span><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"><span style="color:rgb(68,68,68); font-family:Tahoma,'Microsoft Yahei',Simsun; font-size:14px; line-height:21px"></span></span></span></span></span><br />
</span>
</p>
<p>
</p>
<pre name="code" class="java">import java.lang.reflect.Constructor;
import java.lang.reflect.Field;




/*
 * Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,
 * 所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。 




Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。 








 */
public class ReflectTest {
public static void main(String[] args) throws Exception{
String str1 = &quot;abc&quot;;
Class cls1 = str1.getClass();//返回:表示此对象运行时类的 Class 对象。


Class cls2 = String.class;//cls2代表String的class 字节码
Class cls3 = Class.forName(&quot;java.lang.String&quot;);//返回与带有给定字符串名的类或接口相关联的 Class 对象。获取java.lang.String的class对象
System.out.println(cls1 == cls2);//比较cls1是否与cls2代表相同的类  true
System.out.println(cls1 == cls3);//比较cls1是否与cls2代表相同的类  true


System.out.println(cls1.isPrimitive());//false
System.out.println(int.class.isPrimitive());//判断是不是基本类型的 ture
System.out.println(int.class == Integer.class);//false
System.out.println(int.class == Integer.TYPE);//它(Integer)所包装的基本类型(int)的class  true
System.out.println(int[].class.isPrimitive());//数组也是一种类型,但不是基本类型 false
System.out.println(int[].class.isArray());//判断类型是否为Array类型,true


/*****************************反射**************************************/
//new String(new StringBuffer(&quot;abc&quot;));
//Constructor&lt;String&gt;  constructor1 = Class.forName(&quot;java.lang.String&quot;).getConstructor(StringBuffer.class);//本代码与下行代码相同!
Constructor&lt;String&gt;  constructor1 = String.class.getConstructor(StringBuffer.class);//得到参数为StringBuffered的String构造方法的Class构造函数
String str2 = constructor1.newInstance(new StringBuffer(&quot;abc&quot;));//用这个构造器的时候还需要传进来 一个StringBuffer类型的参数
System.out.println(str2.charAt(2));


/****************************Field**********************************/
System.out.println(&quot;*********************************&quot;);
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField(&quot;y&quot;);//要得到某个类身上的字段(成员变量),先得到类的字节码,字节码身上有成员变量的信息。getField(String name)得到某个字段(成员变量),用变量名字来区分到底是要得到哪一个成员变量
//fieldY只是代表类字节码身上的变量,没有对应到对象身上,
//如下:pt1.getClass()==pt2.getClass()==pt3.getClass()
//fieldY的值是多少?是5?错!fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
System.out.println(fieldY.get(pt1));//结果为5


ReflectPoint pt2 = new ReflectPoint(3,8);
   fieldY = pt2.getClass().getField(&quot;y&quot;);//pt2.getClass():得到类ReflectPoint的字节码,getField(&quot;y&quot;):得到类ReflectPoint字节码身上的成员变量y的信息
System.out.println(fieldY.get(pt1));//结果为5


ReflectPoint pt3 = new ReflectPoint(3,20);
   fieldY = pt3.getClass().getField(&quot;y&quot;);//pt3.getClass():得到类ReflectPoint的字节码,getField(&quot;y&quot;):得到类ReflectPoint字节码身上的成员变量y的信息
System.out.println(fieldY.get(pt1));//结果为5
System.out.println(&quot;*********************************&quot;);


Field fieldX = pt1.getClass().getDeclaredField(&quot;x&quot;);//因为变量x是私有的,外界不可见,所以用getDeclaredField来使其可见
fieldX.setAccessible(true);//暴力反射  x是私有的,外界不可用,所以用setAccessible(true)来使其可得到
System.out.println(fieldX.get(pt1));


/*****************************作业示例**********************************/
changeStringValue(pt1);
System.out.println(pt1);
}




private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = obj.getClass().getFields();
for(Field field:fields){
//if(field.getType().equals(String.class)){
if(field.getType() == String.class){//都 是一份,所以用双等号比较好!
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}


}




}


 class ReflectPoint {
private int x;
public int y;


public String str1 =&quot;ball&quot;;
public String str2 = &quot;basketball&quot;;
public String str3 = &quot;itcasdt&quot;;


public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
/*
* 返回一个描述此 Field 的字符串。格式是:该字段(如果存在的话)的访问修饰符,
* 后面跟着字段类型和一个空格,再后面是声明该字段的类的完全限定名,
* 后面跟着一个句点,最后是字段的名称。例如: 
    public static final int java.lang.Thread.MIN_PRIORITY
    private int java.io.FileDescriptor.fd
(non-Javadoc)
* @see java.lang.Object#toString()

* 返回:该对象的字符串表示形式
*/
@Override
public String toString() {
//return super.toString();
return str1 + &quot;::&quot; + str2 + &quot;::&quot; +str3;
}




}</pre>
<br />
<br />


<p>
</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值