---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
Class类:(再讲反射之前必须得先知道Class类)
Class:代表一类事物是一个类,用于描述众java类的一个类
Class类特点:没有构造方法,它的实例对象是各个类在内存中的字节码
如何得到各个类对应的字节码:1、类名.class 2、对象.getClass() 3、Class.forName("类名")-->静态方法
得到字节码的三种方式的验证代码片段:
String str = ""abc";
使用各种方法得到str对象的字节码文件
Class cl1 = String.class;
Class cl2 = str.getClass();
Class cl3 = Class.forName("java.lang.String");//此处类名是类全名
进行判断
sop(cl1 == cl2); //true
sop(cl1 == cl3); //true
打印结果为两个true,证明三种方式得到的字节码都是同一字节码
Class类的几个方法:
Class.isPrinitive();判断一个类是不是基类int.class == Integer.TYPE;
Class.isArray();判断class的类型
只要在源程序中出现的类型,都有各自的class实例对象例如:int[] 、void
java中有九个预定义Class实例对象:八个基本数据类型,一个void.class();
*-*_______________________________________________________________*-*
反射:(JDK1.2)
何为反射:反射就是通过Java类中的各种成分映射成相应的Java类
反射的使用:1、首先得到要调用类的字节码class 2、然后得到要调用类中的方法Method 3、在进行方法的调用(invoke)
Constructor类:获取class类的构造方法,使用相应的构造方法创建相应的对象,所得对象就可以使用相应的类的方法
代码实例片段:
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str = constructor1.newInstance(new StringBuffer("abc"));//传入与constructor1同类型的参数
sop(str.charAt(2)); //c
Field类:获得字节码里某一变量的字段,然后通过对象得到相应的值
代码实例片段:(先定义一个类,然后通过反射得到类实例对象的各项值)
public class ReflectPoint
{
private int x;
public int y;
public ReflectPoint(int x, int y)
{
this.x = x;
this.y = y;
}
}
· 应用↓
ReflectPoint pt1 = new ReflectPoint(3, 5);
Field fieldY = pt1.getClass().getField("y");
sop(fieldY.get(pt1));//5
想要得到私有变量需要使用暴力反射,将其变量设为可见
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);
sop(fieldX.get(pt1));//3
代码实例获取字段并修改:
//首先创建一个类
public class ReflectPoint
{
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = " itcast";
}
//然后对类中的成员获取字段并作替换,具体实现步骤:1、先获得相应对象所有字段 2、遍历得到目标类型变量字段 3、获得字段值,修改后设置对象值
Field[] fields = pt2.getClass().getFields();
for(Field field : fields)
{
if(field.getTYPE == String.class)//字节码对应同一字节码故用 ==
{
String value = (String)field.get(pt2);
value = value.replaace('b', 'a');
field.set(pt2, value);
}
}
Method类:获得类中的方法,再通过方法调用类中对象
代码片段:
Method methodCharAt = String.class.getMethod("charAt", int.class);
sop(methodCharAt.invoke(str, 1));//获取str中的第二个元素,调用静态方法时第一个参数为null,方法返回值由方法本身决定
//
①②③④⑤⑥⑦⑧⑨⑩
用反射的方式执行某个类的main方法:
1、获取需要执行的main方法 2、传入参数调用main方法启动
代码片段:
①String startingClassName = args[0]; //在不明确具体调用的类的时候
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null, (object)new String[]{ });
②Method mainMethod = 类名.class.getMethod("main", String[].class); //明确调用类的类名的时候也可以直接获取其main方法
mainMethod.invoke(null, (object)new String[]{ }); //加Object将数组强转为了能满足JDK1.4的语法,当传入参数只有一个的时候可以省略
数组的反射:
1、具有相同数据类型和相同维度的数组对应相同的字节码文件
2、数组class实例对象.getSuperClass();返回Object对应的class文件即:Object.class
3、基本类型的一维数组可以当做Object类型使用,非基本类型即可当Object也可当Object[]
4、Arrays.asList();处理int[]和String[]差异:基本数据把整个数组当做一个元素
5、怎样得到数组中的元素类型:先取出一个元素,再得到字节码,最后获得类型 a[0].getClass().getName();
数组反射的应用:判断一个数组是否为基本型,如果是对其中的元素进行操作
代码片段:
printObject(a);
private static void printObject(Object obj){
Class cl = obj.class();
if(cl.isArrar()){
int len = Array.getLength(obj);
for(int i=0; i<len; i++){
sop(Array.get(obj, i));
}
}else{
sop(obj);
}
}
反射实现框架功能:
框架与框架要解决的核心问题:框架与工具之间的相互调用框架要解决的核心问题:在不明确调用框架的具体类时,利用反射方式实现运行程序的提前安排
实例代码片段:
InputStream ips = new FileInputStream("config.properties");//当要使用时对配置文件具体配置
Properties props = new properties();
props.load(ips);
ips.close();
String className = props.getProperty("className");
Collection collections = (Collection)class.forName(className).newInstance();
...
collections.add(...);
配置文件的加载:
1、getRealPath(); 查找根目录
2、InputStream ips = 类名.class.getClassLoader().getResourceAsstream("文件名");
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------