1.反射的基石---Class类
1.java程序中的各个java类属于同一类事物,描述这类事物的java类名就是class。
Class cls1=字节码1;
Class cls2=字节码2;
2.如何得到各个字节码对应的实例对象(class类型)
类名:class ,例如,System.class;
对象.getClass(),例如,new Date(),getClass()
//反射主要用第3种
Class.forName(“类名”),例如,Class.forName(“java.util.Data”);
3.反射技术
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
4、应用场景
程序能用了,如何使用后期出现的功能类呢?
常用的作法,会提供一个配置文件,来供以后实现此程序的类来扩展功能。对外提供配置文件,让后期出现的子类直接将类名字配置到配置文件中即可。该应用程序直接读取配置文件中的内容。并查找和给定名称相同的类文件。进行如下操作:
1)加载这个类。
2)创建该类的对象。
3)调用该类中的内容。
应用程序使用的类不确定时,可以通过提供配置文件,让使用者将具体的子类存储到配置文件中。然后该程序通过反射技术,对指定的类进行内容的获取。
5.反射
反射就是把java类中的各种成分映射成相应的java类。
好处:反射技术大大提高了程序的扩展性。
package cn.itcast.day1;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectTest {
private int x;
private int y;
//定义public类型,方便访问
public String str1="abc";
public String str2="abcd";
public String str3="abcdefg";
public ReflectTest(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString()
{
return str1+"--"+str2+"--"+str3;
}
public static void main(String[] args)throws Exception
{
String str1="abc";
Class cls1=str1.getClass();
Class cls2=String.class;
Class cls3=Class.forName("java.lang.String");
System.out.println(cls1==cls2);
System.out.println(int[].class.isArray());
//
String.class.getConstructor(StringBuffer.class);
//获取Constructor构造函数,构造方法反射应用
Constructor constructor1=String.class.getConstructor(StringBuffer.class);
String str2=(String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ReflectTest pt1=new ReflectTest(3,5);
Field fieldY=pt1.getClass().getDeclaredField("y");
Field fieldX=pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);//暴力反射
//看见拿不到,fieldY代表的类中字节码的变量,不代表某个对象。
System.out.println(fieldY.get(pt1));
System.out.println(fieldX.get(pt1));
//fieldY不是对象身上的变量,而是类上,要用它的取对象的值
// ReflectTest pt2=new ReflectTest();
changeStringValue(pt1);
System.out.println(pt1);
}
//改变一组字符串变量c-->a;
private static void changeStringValue(Object obj)throws Exception
{
//字节码变量数组
Field[] fields=obj.getClass().getFields();
for(Field fie:fields)
{
//如果获取的字节码变量类型为String
if(fie.getType()==String.class)
{
//get方法获取变量
String oldValue=(String)fie.get(obj);
String newValue=oldValue.replace('c', 'a');
fie.set(obj, newValue);
}
}
}
}