反射

反射的基石--Class类

1.什么是Class。
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class。
Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则由这个类的实例
对象来确定,不同的实例对象有什么不同的属性值,


Class cls 
Class的实例对象代表字节码。
什么是字节码?
某个类编译后保存在硬盘上的二进制代码。
当我们用到某个类的时候,首先要把该类的字节码加载到内存中,再创建该类的对象。


2.如何得到各个字节码对应的实例对象(Class类型)
 ● 类名.class,例如, System.class;
 ● 对象.getClass(), 例如,new Date().getClass();
 ● Class.forName("类名"), 例如, Class.forName("java.util.Date");
3.九个预定义Class实例对象
 ● 每一个基本类型都对应一个Class对象,void也有对应的Class对象。
 ● 参看Clas.isPrimitive方法帮助
  ps:int.class == Integer.TYPE
4.数组类型的Class实例对象
 ● Class.isArray()
总之,只要在源程序中出现的类型,都有各自的Class实例对象,例如,int[], void...


反射
什么叫反射:发射就是把Java类中的各种成分映射成相应的java类。(传智学员 冯伟立总结)


Constructor类
Constructor类代表某个类中的一个构造方法。
 ● 得到某个类的所有构造方法:
Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
 ● 得到一个构造方法:
Constructor constructor = Class.forName("java.lang.String").getConstructors(StringBuffer.class);
 ● 创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));
 ● Class.newInstance()方法:
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
该方法内部的具体代码,用到了缓存机制来保存默认构造方法的实例对象。


Field类
Field类代表某个类中的一个成员变量。
Ps:字节码比较用 == ,更准确,因为字节码只有一份。
示例:
public static void main(String[] args) throws NoSuchFieldException, Exception {
		
		ReflectPoint rp = new ReflectPoint(6,7);
		// 取得私有成员变量
		Field fieldx = rp.getClass().getDeclaredField("x");
		// 取得公有成员变量
		Field fieldy = rp.getClass().getField("y");
		
		// 获取私有变量的值
		fieldx.setAccessible(true);
		int vlauex = fieldx.getInt(rp);
		// 获取公有变量的值
		int valuey = fieldy.getInt(rp);
		
		System.out.println(vlauex);
		System.out.println(fieldy);
	}



Method类
Method类某个类中的一个方法。
Ps:如果传递给Method对象的invoke()方法的第一个参数为null,说明给对象是一个静态方法。


用反射方式执行某个类中的main方法
通过反射方式来调用这个main方法时,按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素都对应一个
参数,当把一个字符串数组作为参数传递给invoke方法时,javac会按照jdk1.4的语法进行处理,即,把数组打散成若干个单独的
参数。所以,在给main方法传递参数时,不用使用代码 mainMethod.invoke(null, new String[] {"xxx","xxx",...}),否则会出现
参数类型不对问题。


解决办法:
mainMethod.invoke(null, new Object() {new String[] {"xxx","xxx",...}});
mainMethod.invoke(null, (Object)new String[] {"xxx","xxx",...})


示例:
public static void main(String[] args) throws NoSuchFieldException, Exception {
		
		ReflectPoint rp = new ReflectPoint(6,7);		
		Method methodMain = rp.getClass().getMethod("main", String[].class);
		methodMain.invoke(null, (Object)new String[] {"a", "b", "c"});
	}



数组与Object的关系及其反射类型
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即,具有相同的Class实例对象。
基本类型的一维数组可以被当做Object类型使用,不能被当做Object[]类型使用,非基本类型的一维数组,既可以当做Object类型
使用,又可以当做Object[]类型使用。


反射的作用-->实现框架功能

package it.practise.com.reflect;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;

public class ReflectTest {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		InputStream is = new FileInputStream("config.properties");
		Properties pros = new Properties();
		pros.load(is);
		is.close();
		String className = pros.getProperty("className");
		
		Collection collections = (Collection)Class.forName(className).newInstance();
		ReflectPoint pt1 = new ReflectPoint(3,3);
		ReflectPoint pt2 = new ReflectPoint(5,5);
		ReflectPoint pt3 = new ReflectPoint(3,3);
		collections.add(pt1);
		collections.add(pt2);
		collections.add(pt3);
		collections.add(pt1);
		System.out.println(collections.size());
	}

}

ReflectPoint类
<pre name="code" class="java">package it.practise.com.reflect;

import java.util.Arrays;


public class ReflectPoint {
	
	private int x = 1;
	public int y = 2;
	ReflectPoint(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public int sum() {
		return x + y;
	}
	
	public static void main(String[] args) {
		System.out.println(Arrays.asList(args));
	}
}


 

config.properties文件内容
className=java.util.ArrayList
 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值