反射

反射

反射的基石:Clasee类
  • JAVA程序中的各个Java类属于同一类事物,描述这类事物的Java类名即使Class 。
  • 一个Java被加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类字节码不相同,所以他们在内存中的内容是不相同的,这一个个的空间分别用一个Class对象来表示,这些对象显然具有相同的类型,这个类型就是Class。
  • 如何得到一个字节码对应的实例对象
类名.class ,例如System.class.
对象.getClass() ,例如:new Date().getClass() .
Class.forName("类的完整名称,加包名") , 例如:Class.forName("java.util.Date") 。
  • 九个预定义Class对象:8个基本数据类型,和void。
public class ReflectTest {

	public static void main(String[] args)throws Exception {
		
		String srt = "abc" ;
		//Class对象的第一种获取方法:类名.calss
		Class class1 = String.class;
		//Class对象的第二种获取方法:对象.getClass();
		Class class2 = srt.getClass();
		//Class对象的第三种获取方法:Class.forName();
		//class的获得过程:当虚拟机中还没有这个对象的字节码时,通过类加载器从文件中加载,并缓存起来。
		//当再次来去这个对象的字节码时直接返回,缓存起来的字节码对象。
		Class class3 = Class.forName("java.lang.String");
		
		//类的字节码只有一份,所以都想等
		System.out.println(class1==class2);
		System.out.println(class1==class3);
		
		
		System.out.println(class1.isPrimitive());
		System.out.println(int.class.isPrimitive());
		//int的字节码是预定义的,integer是包装类,不相等。
		System.out.println(int.class==Integer.class);
		//Integer.TYPE是返回的int类型,所以相等。
		System.out.println(int.class==Integer.TYPE);
	}
}

反射就是将Java类中的各种成分映射成相应的java类。例如,类中的组成成分:成员变量、构造方法、方法、包信息等分别对应Field、Constructor、Method、Package等。

Constructor类

  • Constructor类代表某个类中的构造方法
  • 一个类中的构造方法可能有很多,我们可以根据参数列表进行区分。
  • 得到某个类中的构造方法:根据参数类型进行区分。将参数类型的字节码传进去,就可以得到相应的方法。
public class ReflactTest2 {

	public static void main(String[] args)throws Exception {
		Class c =Class.forName("Person");
		
		//调用默认的构造函数
		Person p = (Person)c.newInstance();
		//默认的构造方法,参数为空
		Constructor cons = c.getConstructor(null);
		Person p1 =(Person)cons.newInstance();
		
		//通过参数类型,获得一个构造方法对象
		//调用构造方法对象的newInstance()方法,将实际参数传递进去
		Constructor cons2 = c.getConstructor(String.class,int.class) ;
		Person p2 =(Person)cons2.newInstance("andy",12);	
	}
}


class Person{
	private int age ;
	private String name ;
	
	public Person(){
		System.out.println("Person run.."+this.name+":"+this.age);
	}
	
	public Person(String name,int age){
		this.age = age ;
		this.name = name ;
		System.out.println("Person run.."+this.name+":"+this.age);
	}
}

Field类

  • Field类代表了某个类中的属性
  • 通过属性名字来区分。
public class ReflactTest2 {

	public static void main(String[] args)throws Exception {
		Class c =Class.forName("Person");
		
		//调用默认的构造函数
		Person p = (Person)c.newInstance();
		
		//获得Field对象,是属于字节码的。对于private的属性要使用getDeclaredFile才可以看见。
		Field age = c.getDeclaredField("age");
		//对于private的变量,要通过下面的方法暴力反射才可以修改
		age.setAccessible(true);
		//调用Field对象的set方法设置具体person对象的age
		age.set(p, 10);
		
		Field name = c.getDeclaredField("name");
		name.setAccessible(true);
		name.set(p, "zhangsan");
		//不是private的属性使用getField就可以拿到。
		Field address = c.getField("address");
		address.set(p, "beijing");
		
		System.out.println(p.toString());
	}
}
class Person{
	private int age ;
	private String name ;
	public String address;<pre name="code" class="java">class Person{
	private int age ;
	private String name ;
	public String address;
	
	public Person(){
		System.out.println("Person run.."+this.name+":"+this.age);
	}
	
	public void show(){
		System.out.println("Pserson show ...");
	}
	
	public void show(String p){
		System.out.println("Pserson show ..."+"String:"+p);
	}
	
	private void show(int i){
		System.out.println("private method show ..."+"String:"+i);
	}
}
 
  

Method类

  • Method类代表某个类中的一个成员方法
  • 要得到一个方法,要知道方法名和参数类型,还有类的字节码
public class Reflact3 {
	public static void main(String[] args)throws Exception{
		Class c = Class.forName("Person");
		Object p = c.newInstance();
		
		//获得一个方法要 方法名、方法的参数列表
		Method m1 = c.getMethod("show", null);
		m1.invoke(p, args);
		
		Method m2 = c.getMethod("show", String.class);
		m2.invoke(p, "nihao");
		
		//私有方法直接使用getMethos获取会报java.lang.NoSuchMethodException:
		//
		Method m3 = c.getDeclaredMethod("show", int.class) ;
		//不设置accessible为true会报下面的错误。
		//can not access a member of class Person with modifiers "private"
		m3.setAccessible(true);
		m3.invoke(p, 1) ;
	}
}

Peson类:
class Person{
	private int age ;
	private String name ;
	public String address;
	
	public Person(){
		System.out.println("Person run.."+this.name+":"+this.age);
	}
	
	public void show(){
		System.out.println("Pserson show ...");
	}
	
	public void show(String p){
		System.out.println("Pserson show ..."+"String:"+p);
	}
	
	private void show(int i){
		System.out.println("private method show ..."+"String:"+i);
	}
}

反射的作用:实现框架功能

  • java框架就是一些类和接口的集合,通过这些类和接口协调来完成一系列的程序实现。
  • 框架在开发时,无法知道后来开发要调用的类名,所以无法直接通过new某个对象,而是通过反射来创建对象。
public class ReflactTest {
	public static void main(String[] args)throws Exception {
		//加载配置文件
		Properties proper = new Properties();
		InputStream is = new FileInputStream("G:\\eclipse\\Reflect\\src\\init.property");
		proper.load(is);
		//拿到配置文件中,对应的类名
		String soundcard = proper.getProperty("soundCard");
		String netcard = proper.getProperty("netCard") ;
		//根据上面的类名,通过反射获得类的对象
		pci p1 = (pci)Class.forName(soundcard).newInstance();
		pci p2 = (pci)Class.forName(netcard).newInstance() ;
		//调用对象的方法
		p1.run();
		p2.run();
	}
}

class SoundCart implements pci{
	public void start(){
		System.out.println("Sound is start");
	}
	public void close(){
		System.out.println("Sound is close");
	}
	public void run(){
		start();
		close();
	}
}

class netCard implements pci{
	@Override
	public void start() {
		System.out.println("netCard is start");	
	}
	@Override
	public void close() {
		System.out.println("netCard is start");	
	}
	public void run(){
		start();
		close();
	}
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值