黑马程序员——09 高新技术(二)一个例子学会使用反射机制

------- android培训java培训、期待与您交流!----------

当我们写好一个程序时,Java 语言把每个单独的类 Class 和接口 Implements 编译成单独的一个 . class 文件,这些文件对于 Java 运行环境来说就是一个个可以动态加载的单元。此外这些class文件就是这些类或接口的字节码文件,为了操作这些字节码文件,java把这些字节码文件归为Class类。

那么怎样来理解Class类呢?

类就是一些具有相同特性的对象的抽象形式,比如Person类,就把人的姓名,年龄,身高等共有的数据给抽象出来。

而Class类就是所有类字节码文件对象的抽象形式,所有的类都是具有字段,构造方法,成员方法这些相同的元素,

Class类就把这些类共有的特性分为了Field,Constructor,Method类。

而反射就是建立在Class类的基础上来动态的获取类中的信息,调用这些类的方法和属性,要想操作这些类必须先获得这些类的字节码文件对象。比如Person类就具有自己特有的字节码文件,他的对象P1和P2所对应的类的字节码文件都是一样的。

下面通过一个例子就把关于反射的大部分操作方法给展现出来。

//定义一个Person类,分别有公有和私有的构造方法、字段和方法,然后用反射来操作这个类
public class Person {
	private String namePrivate;
	public static int ageStatic;
	public String namePublic;
	public int agePublic;
	
	
	 Person() {
		
	}
	
	public Person(String namePublic,int agePublic)
	{
		this.namePublic = namePublic;
		this.agePublic = agePublic;
		System.out.println("我是公有构造方法"+"公有字段"+namePublic+agePublic);
	}
	
	public Person(int agePublic)
	{
		this.agePublic = agePublic;
	}
	
	private Person(String namePrivate)
	{
		this.namePrivate = namePrivate;
		System.out.println("我是私有有构造方法"+"私有字段"+namePrivate);
	}

	public Person getPersonPublic(String namePublic ,int agePublic )
	{
		this.agePublic = agePublic;
		this.namePublic = namePublic;
		Person p = new Person();
		return p;
	}
	
	public int  getAgePublic()//空参数的构造方法
	{
		return agePublic;
	}
	
	private String getNamePrivate(String name)
	{
		return namePrivate;
	}
	
	public static int getAgeStatic(int age)
	{
		Person.ageStatic = age;
		return ageStatic;
	}
}


 

import java.lang.reflect.Constructor;


import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.activation.FileDataSource;

import cn.cn.cn.Student;

public class ClassDemo {

	public static void main(String[] args) throws Exception
	{
		new Student();
		/*
		 * 有三种方式可以得到Person类的Class
		 * 方式一:知道Person的一个对象p
		 *        Class c1 = p.getClass();
		 * 方式二:知道有个类叫Person  
		 *        Class c2 = Person.class;
		 * 方式三:知道有个类叫Person  此种方式的字符串参数要包括包名,一般是通过配置文件获得的
		 *        Class c3 = Class.forName("Person");
		 */
		
         //方式一:必须要先有个对象
		 Person p = new Person();
		 Class c1 = p.getClass();
		 
		 //方式二
		 Class c2 = Person.class;
		 
//		 方式三
		 Class c3 = Class.forName("Person");//Person保存在默认包中
		 //如果我们定义一个Student类他的包名为 cn.cn.cn,用之前先导入包,最上面:import cn.cn.cn.Student;
		 Class c4 = Class.forName("cn.cn.cn.Student");
		 System.out.println(c4);
		 /*
1		  * 构造方法的获得方式
		  * 
		  * 1.获得公有的构造方法
		  *  1.1获得所有的公有方法
		  *  1.2获得指定的公有方法
		  * 2.获得所有的构造方法
		  *  2.1获得所有的方法
		  *  2.2获得指定的私有方法
		  */
		 
		 //1.1获得所有公有的构造方法,调用Class对象的getConstructors方法,他会返回返回一个包含某些 Constructor 对象的数组
		     Constructor[] cons = c1.getConstructors();
		     for(Constructor s : cons)
		     {
		    	 System.out.println(s); //打印结果public Person(int)  public Person(java.lang.String,int)
	    	 
		     }
		   // 1.2 获得指定的公有方法,调用Class方法的getConstructor方法,返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
		         //指定的方法就是将构造方法的参数值传入
		     Constructor con = c1.getConstructor(String.class,int.class);
		     System.out.println(con);  //  public Person(java.lang.String,int)
		    
		   // 2.获得所有的私有方法以及指定的私有方法,与上面的方法类似,就多了个Declared关键字
		     Constructor[] conprs = c1.getDeclaredConstructors();
		     Constructor conpr = c1.getDeclaredConstructor(String.class);
		   
    /***************************************************************************************/
     /*
2      * 获得字段的方法
        2.1获得所有的公有字段
        2.2获得所有的字段
        2.3获得指定的私有字段
        
      */     
		     
		//获得所有的公有字段
		     Field[] filed = c1.getFields(); 
		//获得所有的 私有有字段     
		     Field[] fieldpr = c1.getDeclaredFields();
		//获得指定的私有字段namePrivate
		     Field f = c1.getDeclaredField("namePrivate");
		     System.out.println(f);
   /***************************************************************************************/	 
 /*
3     * 获得字段的方法
		 3.1获得所有的公有方法
		 3.2获得所有的方法
		 3.3获得指定的公有方法
		 3.4获得静态方法
*/          
	//3.1获得所有的公有方法
		  Method []  ms = c1.getMethods();
	//3.1获得所有的方法 	 
		  Method []  mps = c1.getDeclaredMethods();
	//3.3获得指定的公有方法,调用getDeclaredMethod(String name ,Class<?>... parameterTypes)
    //  他又两个参数,name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组,
	//它按声明顺序标识该方法的形参类型。	 
		  Method m = c1.getDeclaredMethod("getNamePrivate", String.class);
		  //如果想获取空参数的构造方法,将参数表写为null就行了
		   Method mnull = c1.getMethod("getAgePublic", null);
	//3.4获得静态方法,和普通的获得方法没什么不同
		  Method mm = c1.getMethod("getAgeStatic", int.class);
		  /***************************************************************************************/
    /*
4       如何利用反射实例化一个对象,并使用它的方法
        4.1利用方式实例化一个对象
           4.1.1利用默认的无参构造函数实例化一个对象
           4.1.2利用指定的公共的构造函数实例化一个对象
           4.1.3利用指定的私有的构造函数实例化一个对象
           
                 
        4.2利用反射使用方法
           4.2.1使用公共的方法
           4.2.2使用私有的方法
           4.2.3使用静态方法
 *  */		
		  
		  // 4.1.1利用默认的无参构造函数实例化一个对象
		  Person p1 = (Person)c1.newInstance();
		  // 4.1.2利用指定的公共的构造函数实例化一个对象
		  Constructor con1 = c1.getConstructor(String.class,int.class);
		  Person p2 =  (Person)con1.newInstance("liming",20);
		  System.out.println(p2.agePublic+p2.namePublic);
		  //利用指定的私有的构造函数实例化一个对象
		  Constructor con3 = c1.getDeclaredConstructor(String.class);
		  //私有的必需要设置访问权限,否则不能访问,对于字段和方法也是一样的
		   con3.setAccessible(true);
		   con3.newInstance("wang");
		  
		   
		   // 4.2.1使用公共的方法
		   Method m1 = c1.getMethod("getAgePublic", null);
		   Object obj = c1.newInstance();
		   
		   int age = (Integer) m1.invoke(obj, null);
		   //4.2.2使用私有的方法,与上面类似,只要设置权限就可以了
		   //4.2.3使用静态方法。和上面类似,只要invoke的第一个参数设为null
		   Method m2 = c1.getMethod("getAgeStatic", int.class);
		   int age1 = (Integer) m2.invoke(null, 24);
		   System.out.println(age1);
		   
		   
	}
}


 

 ------- android培训java培训、期待与您交流!-------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值