反射和内省


1.反射:一个类有多个组成部分,比如成员方法,成员变量,构造函数。反射就是加载类,并且去解剖出类的各个组成部分。

2.加载类:java中有一个Class类用于代表某一个类的代码。

3.Class类既然代表某个类的字节码,那么必然提供了加载某个字节码的方法,例如:

forName(),forName()用于加载某个类的字节码到内存中,并且使用Class对象进行封装。

另外二种得到Class对象方式:

    1.类名.class:Person.class

    2.对象.getClass().:new Person().getClass()

4.内省(Introspector)

     主要用于操作javabean的属性

内省访问javabean属性的二种方式。

     1.通过PropertyDescriptor类操作javabean的属性。

     2.通过Introspector类获得bean对象的beaninfo,然后通过BeanInfo来获取属性的描述器

(PropertyDescriptor),通过属性描述器就就可以获取属性的gettersetter方法,最后通过反射调用这些方法.

5..反射案例

    1.创建一个Person类.

package com.cn.fanshe;

import java.awt.List;
import java.io.InputStream;

public class Person {
	public String name="aaa";
	private String passwd;
	private static int num;
	public Person(){
		System.out.println("person");
	}
	public Person(String name){
		System.out.println(name);
	}
	public Person(String name,String passwd){
		System.out.println(name +"and"+ passwd);
	}
	private Person(List list){
		System.out.println("list");
	}
	public void add(){
		System.out.println("add");
	}
	public void add(String name){
		System.out.println(name);
	}
	public Class[] add(String name,int[] i){
		return new Class[]{};
	}
	private void add(InputStream  in){
		System.out.println(in);
	}
	public static void add(int passwd){
		System.out.println(passwd);
	}
	public static void main(String[] args) {
		System.out.println("main");
	}
}

    2.获取类的字节码的三种方式

package com.cn.fanshe;

public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
	//第一种方式:反射,加载类,参数是类的完整类名
	Class  cl=Class.forName("com/cn/fanshe/Person.java");
	
	//第二种方式:对象.getClass().
	Class  clazz=new Person().getClass();
	
	//第三种方式:类名.class
	Class  cla=Person.class;
	
	
}
}
   3.反射类的构造函数

package com.cn.fanshe;

import java.awt.List;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
/*
 * 反射类的构造函数
 */
public class Demo2 {
	
			//public Person:反射构造函数,创建类的对象
	public void test1() throws Exception{
		//加载类,将类的字节码加载到内存中
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Constructor c=clazz.getConstructor(null);
		Person p=(Person)c.newInstance(null);
		System.out.println(p.name);
	}
	
	//public Person(String name):
	public void test2() throws Exception{
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Constructor c=clazz.getConstructor(String.class);
		Person p=(Person)c.newInstance("hello");
		System.out.println(p.name);
	}
	
	//public Person(String name,String passwd)
	public void test3() throws Exception{
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Constructor c=clazz.getConstructor(String.class,String.class);
		Person p=(Person)c.newInstance("hello","1232");
		System.out.println(p.name);
	}
	
	//private  Person(List list);
	public void test4() throws Exception{
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Constructor c=clazz.getDeclaredConstructor(List.class);//当构造函数设置为private,反射时必须使用getDeclaredConstructor();
		c.setAccessible(true);//当构造函数设置为private时,设置可以强制反射
		Person p=(Person)c.newInstance(new ArrayList());
		System.out.println(p.name);
	}
	
	//创建对象的另一种途径,等效于test1()。当构造函数无参数时使用.
	public void test5() throws Exception{
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Person p=(Person)clazz.newInstance();
		System.out.println(p.name);
	}
	
}
            3.反射类的方法

package com.cn.fanshe;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;

/*
 * 反射类的成员方法
 */
public class Demo3 {
	//反射类的成员方法:public void add();
	public void test1() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Method method=clazz.getMethod("add",null);
		method.invoke(p, null);
	}
	//public void add(String name);
	public void test2() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Method method=clazz.getMethod("add",String.class);
		method.invoke(p, "hello");
			
	}
	//public void add(String name,int[] i);
	public void test3() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Method method=clazz.getMethod("add",String.class,int[].class);
		Class[] ca=(Class[])method.invoke(p, "qwer",new int[]{1,23});
	}
	
	//private void add(InputStrream in);
	public void test4() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Method method=clazz.getDeclaredMethod("add",InputStream.class);
		method.setAccessible(true);
		method.invoke(p, new FileInputStream("c://1.txt"));
	}
	
	//public static void add();
	public void test5() throws Exception{
		//因为反射静态方法,所以对象为null;
		Class clazz=Class.forName("com/cn/fanshe/Perosn.java");
		Method method=clazz.getMethod("addd",int.class);
		method.invoke(null,334);
	}
}

            4.反射类的字段

package com.cn.fanshe;

import java.lang.reflect.Field;

/*
 * 反射类的字段或者说是属性
 */
public class Demo5 {
	//反射字段:public String name="aaaa";
	public void test1() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Field f=clazz.getField("name");
		//f.get(p):获取字段的值
		String s=(String)f.get(p);
		System.out.println(s);
		//获取字段的类型
		Class  cl=f.getType();
		System.out.println(cl);
		
		//设置字段的值
		f.set(p, "ghj");
		System.out.println(p.name);
	}
	
	//反射字段:private String passwd;
	public void test2() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Field f=clazz.getDeclaredField("passwd");
		f.setAccessible(true);
		System.out.println(f.get(p));
		
	}
	//反射字段:private static int num;
	public void test3() throws Exception{
		Person p=new Person();
		Class clazz=Class.forName("com/cn/fanshe/Person.java");
		Field f=clazz.getDeclaredField("num");
		f.setAccessible(true);
		String s=(String)f.get(p);
		System.out.println(s);
	}
}


6.内省的案例

      1.创建一个Perosnd类

package com.cn.introspector;

public class Person {
	private String name;
	private int passwd;
	private static int  num;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPasswd() {
		return passwd;
	}
	public void setPasswd(int passwd) {
		this.passwd = passwd;
	}
	public static int getNum() {
		return num;
	}
	public static void setNum(int num) {
		Person.num = num;
	}
	
	
}

              2.获取属性和属性的数据类型

package com.cn.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class Demo {
	//遍历类的属性
	public void test1() throws Exception{
		BeanInfo info=Introspector.getBeanInfo(Person.class,Object.class);//得到自己的属性,除去了Object的属性了
	    PropertyDescriptor[]  pd=info.getPropertyDescriptors();//获取属性描述器
	    for (PropertyDescriptor pr : pd) {
			System.out.println(pr.getName());//获取bean里面的属性名
		}
	}
	//操作bean的指定属性;name
	public void test2() throws Exception{
		Person p=new Person();
		PropertyDescriptor pd=new PropertyDescriptor("name",Person.class);
		//操作属性的值,给属性赋值.
		Method method=pd.getWriteMethod();//相当于public void setName();
		method.invoke(p, "heool");
		//操作属性的值,读取属性的值
		Method md=pd.getReadMethod();
		System.out.println(md.invoke(p, "name"));
		
	}
	
	
	//获取属性的数据类型
	public void test3() throws Exception{
		Person p=new Person();
		PropertyDescriptor  pd=new PropertyDescriptor("name", Person.class);
		System.out.println(pd.getPropertyType());
	}
	public static void main(String[] args) throws Exception {
		new Demo().test3();
	}
}

7.反射和内省的区别

   内省,是对javabean对象的操作,反射就是把一个普通类中的每个组成部分都可以单独取出来,对每一个成员的调用或者修改不必依赖于new对象。



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值