zoukankan      html  css  js  c++  java
  • java反射

    本文按照以下思路帮助自己和路人理清反射。

    1.什么是反射?

    2.反射能干什么?

    3.怎么用?

    4.案例实操:

    5.总结:

    一、什么是反射?

        百度百科:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及

      动态调用对象方法的功能称为java语言的反射机制。

      说的通俗一点,反射是在程序编译完成后,在.class运行阶段起作用的,你给我传过来什么,我都能访问它祖宗十八代,从而达到我的目的。重点在于动态,动态指的是运行阶段,而非编译阶段。

    二、反射能干什么?

      常见的有加载数据库驱动中Class.forName(driverClass),还有许多框架例如spring也大量的使用反射,还有自己的项目中抽取dao层公共方法写到BaseDaoImpl中需要知道传递的实体类型等等,都可以通过反射来获取。

    三、怎么用?

      三种方式可以选择,总之是要获取Class类对象

      3.1.通过对象(不常用,对象都有了还反过用对象再反射属性方法,多此一举)

        Person p = new Person();

        Class<? extends Person> clazz = p.getClass();

      3.2.通过类名(不常用,没有必要)

        Class<? extends Person> clazz = Person.class();

      3.3.通过字符串全类名(常用,一般情况下,我们没法传递过去一个类对象,但是我们可以通过该类的全限定名,间接得到类的信息)

        Class<?> clazz = Class.forName("com.xx.myReflect");

    四、案例实操

      前面都很简单,下面就使用第三种方式,具体测试反射在字段,普通方法,构造方法上的一些使用,其余的类似,自己探索,被测试的类如下。

      4.1 测试字段

      

    @Test
    	public void testField(){
    		try {
    			//通过反射在运行期间加载MyReflect类的.class文件,得到Class对象,Class对象的详细描述了呗代理类
    			Class<?> clazz =  Class.forName("com.cissst.vo.MyReflect");
    			//因为要给字段中设值,因此产生Reflect的实例,父类是Object
    			Object object = clazz.newInstance();
    			//得到本类(不包含父类)中的声明字段数组
    			Field[] fields = clazz.getDeclaredFields();
    			//循环设置字段值,输出字段值
    			for(Field f : fields){
    				//因为某些字段或者方法是私有的,反射需要将此标识设置为true
    				f.setAccessible(true);
    				//判断如果当前字段类型是否是Integer
    				//如果使用getName,获取的是全限定名
    				if(f.getType().getSimpleName().equals("Integer")){
    					//是设置为1
    					f.set(object, 1);
    				}
    				//判断如果当前字段类型是否是String
    				if(f.getType().getSimpleName().equals("String")){
    					//是设置为..
    					f.set(object, "秦琼");
    				}
    				//最后输出,腰肢具体详情请查看API
    				System.out.println(f.get(object));
    			}
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (InstantiationException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		}
    	}
    

      4.2 测试方法

    /*
    	 * 测试普通方法
    	 */
    	@Test
    	public void testMethod(){
    			try {
    				//通过反射在运行期间加载MyReflect类的.class文件,得到Class对象,Class对象的详细描述了呗代理类
    				Class<?> clazz = Class.forName("com.cissst.vo.MyReflect");
    				//产生Reflect的实例,父类是Object
    				Object object = clazz.newInstance();
    				//指定方法名,指定参数类型,得到该方法,还有方法查API,很好用
    				Method method = clazz.getMethod("method", String.class);
    				//执行此方法
    				method.invoke(object, "李逵");
    			} catch (Exception e) {
    				e.printStackTrace();
    			} 
    	}
    

      4.3 测试构造方法

      

    /*
    	 * 测试构造方法
    	 * 
    	 */
    	@Test
    	public void testConstractorMethod(){
    		try {
    			//通过反射在运行期间加载MyReflect类的.class文件,得到Class对象,Class对象的详细描述了呗代理类
    			Class<?> clazz = Class.forName("com.cissst.vo.MyReflect");
    			//调用无参构造
    			Constructor<?> constructor = clazz.getDeclaredConstructor();
    			//通过无参构造实例化得到类对象
    			Object obj1 = constructor.newInstance();
    			//看得到的ojb和MyReflect是否是同一宗亲
    			System.out.println(obj1 instanceof MyReflect);
    			//得到所有的构造
    			Constructor<?>[] constructors = clazz.getDeclaredConstructors();
    			//循环操作构造
    			for(Constructor<?> con : constructors){
    				//这里做个简单的判断,实际可能比这更复杂
    				if(con.getParameterCount()==0){
    					//无参构造实例化
    					Object ojb2 = con.newInstance();
    					//有参构造
    				}else if(con.getParameterCount()==2){
    					//有参构造实例化
    					Object ojb3 = con.newInstance(1,"林彪");
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 
    	}
    

    被测试类:

    package com.cissst.vo;
    
    /**
     * 普通类:用此类测试反射
     * @author phoebe
     */
    public class MyReflect{
    	
    	//字段
    	private Integer id;
    	private String name;
    	
    	
    	/*
    	 * 无参构造方法
    	 */
    	public MyReflect(){
    		System.out.println("无参构造is running");
    	}
    	
    	/*
    	 * 有参构造方法
    	 */
    	public MyReflect(Integer id,String name){
    		this.id = id;
    		this.name = name;
    		System.out.println("有参构造");
    	}
    	
    	/*
    	 * 无参普通方法
    	 */
    	public void method(){
    		System.out.println("无参普通方法");
    	}
    	/*
    	 * 无参普通方法
    	 */
    	public void method(String str){
    		System.out.println("有参普通方法");
    	}
    	
    }
    

    五、总结

      反射使得代码更灵活,可以提高复用性。

    Best Regards
  • 相关阅读:
    POJ 3660 Cow Contest (floyd求联通关系)
    POJ 3660 Cow Contest (最短路dijkstra)
    POJ 1860 Currency Exchange (bellman-ford判负环)
    POJ 3268 Silver Cow Party (最短路dijkstra)
    POJ 1679 The Unique MST (最小生成树)
    POJ 3026 Borg Maze (最小生成树)
    HDU 4891 The Great Pan (模拟)
    HDU 4950 Monster (水题)
    URAL 2040 Palindromes and Super Abilities 2 (回文自动机)
    URAL 2037 Richness of binary words (回文子串,找规律)
  • 原文地址:https://www.cnblogs.com/pecool/p/8414222.html
Copyright © 2011-2022 走看看