欢迎来访...
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

黑马程序员——反射总结

Posted on 2014-03-13 16:26  天赐绝尘  阅读(95)  评论(0编辑  收藏  举报

---------------------- 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培训、期待与您交流! ----------------------