• 【Android开发经验】使用反射,得到的类的字段、方法、并实现了简单的调用


    本文后推出Android的ICO框架做准备,所以,假设你想要一个最近的一项研究Android的ICO学生框架。你可以稍微看一下。

    首先,简介一下Java里面的反射。

    JAVA反射机制是在执行状态中,对于随意一个类,都可以知道这个类的全部属性和方法。对于随意一个对象,都可以调用它的随意一个方法和属性。这样的动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

    不知道这种一段解释,你是否能看懂。假设更简单的说。反射就是能够依据你给出类名实例化出一个实实在在的对象。所以,对象的实例化就不是写死的了。我们能够依据传入的类名不同,从而能够实例化出不同的对象。这种方式能够和工厂设计模式非常好的结合,从而能够更加灵活的创建对象。

    以下。我们简单的介绍一下怎样使用反射来进行对象的创,以及方法、字段的获取与使用。

    首先,给出要用的实体类的代码,重点注意一下字段和方法的权限的修饰符

    package edu.qust.demo;
    
    /**
     * 
     * @ClassName: Person
     * @Description: Person实体类
     * @author: ZhaoKaiQiang
     * @time: 2014-7-18上午10:41:23
     * @version: V1.0
     */
    public class Person {
    
    	private int age;
    	private String name;
    	protected int height;
    	public String school;
    
    	Person(){
    		this.name = "Person";
    		age = 22;
    	}
    	
    	Person(String name) {
    		this.name = name;
    	}
    
    	private String showName(String _name) {
    		return "My name is " + _name;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	@Override
    	public String toString() {
    		return "My name is " + name + ", i'm " + age + " years old";
    	}
    }

    以下,我们開始介绍。在Java中,怎样使用代码实现反射。

    以下是測试程序

    package edu.qust.demo;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Main {
    
    	private static Person person;
    	private static Class<Person> cls;
    
    	@SuppressWarnings("unchecked")
    	public static void main(String[] args) {
    
    		person = new Person("Zhao");
    		cls = (Class<Person>) person.getClass();
    
    		creatClassByReflection();
    		printAllMethods();
    		printAllFileds();
    		invokePrivateMothod();
    	}
    
    	/**
    	 * 利用反射创建对象
    	 */
    	private static void creatClassByReflection() {
    		try {
    			Person accpTeacher = (Person) Class.forName("edu.qust.demo.Person")
    					.newInstance();
    			System.out.println(accpTeacher.toString());
    			System.out.println();
    		} catch (InstantiationException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    	}
    
    	/**
    	 * 获取并调用私有方法
    	 */
    	private static void invokePrivateMothod() {
    		try {
    			// 获取方法名为showName,參数为String类型的方法
    			Method method = cls.getDeclaredMethod("showName", String.class);
    			// 若调用私有方法。必须抑制java对权限的检查
    			method.setAccessible(true);
    			// 使用invoke调用方法。而且获取方法的返回值。须要传入一个方法所在类的对象,new Object[]
    			// {"Kai"}是须要传入的參数,与上面的String.class相相应
    			String string = (String) method.invoke(person,
    					new Object[] { "Kai" });
    			System.out.println(string);
    		} catch (NoSuchMethodException e) {
    			e.printStackTrace();
    		} catch (SecurityException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			e.printStackTrace();
    		} catch (InvocationTargetException e) {
    			e.printStackTrace();
    		}
    	}
    
    	/**
    	 * 获取并打印全部的字段名
    	 */
    	private static void printAllFileds() {
    		Field[] field = cls.getDeclaredFields();
    		System.out.println("getFields():获取全部权限修饰符修饰的字段");
    		for (Field f : field) {
    			System.out.println("Field Name = " + f.getName());
    		}
    		System.out.println();
    	}
    
    	/**
    	 * 获取并打印全部的方法名
    	 */
    	private static void printAllMethods() {
    		Method[] method = cls.getDeclaredMethods();
    		System.out.println("getDeclaredMethods():获取全部的权限修饰符修饰的Method");
    		for (Method m : method) {
    			System.out.println("Method Name = " + m.getName());
    		}
    		System.out.println();
    	}
    }
    

    以下是上面的測试程序的输出结果

    My name is Person, i'm 22 years old
    
    getDeclaredMethods():获取全部的权限修饰符修饰的Method
    Method Name = toString
    Method Name = showName
    Method Name = setAge
    Method Name = getAge
    
    getFields():获取全部权限修饰符修饰的字段
    Field Name = age
    Field Name = name
    Field Name = height
    Field Name = school
    
    My name is Kai
    

    在java.lang.reflect包中,提供了类和接口,来获得关于类和对象的反射信息。


    在这里,我们眼下仅仅关注Field和Method这两个类,分别代表类的成员变量和方法。

    除此之外。在java.lang.Class。还有个反射须要用到的非常重要的类,Class,这个类中封装了一个类全部的信息,包含各种全县修饰符修饰的成员变量和方法。因此,我们能够用这个类,来获取类的各种信息。Class继承自Object,利用Object.getClass能够获取到某对象执行时类的 Class 对象。

    我们的操作,主要就是获取某个类的Class对象。然后利用这个对象,就能够获取到某个类全部的成员变量以及方法,而且能够对随意权限修饰符修饰的方法进行调用,注意。是随意哦,即使是private修饰的类的方法。我们也能够利用反射进行调用,所以说反射能够说是相当逆天啊。

    首先看第一个方法的输出

    My name is Person, i'm 22 years old

    在这里,我们利用一个类的String字符串的名字,实例化出了一个对象。这就是上面所说的。依据传入的字符串的不同,能够创建出不同的对象。

    调用newInstance方法,Java会去找默认的构造函数,完毕对象的初始化,因此得到了这种结果。

    再看第二个方法的输出

    getDeclaredMethods():获取全部的权限修饰符修饰的Method
    Method Name = toString
    Method Name = showName
    Method Name = setAge
    Method Name = getAge

    我们使用getDeclaredMethods这种方法,获取到了类里面全部的方法,然后我们进行遍历,将类名进行简单的输出。

    第三个方法的结果和第二个差点儿相同,仅仅只是就是把Method换成了Filed,然后把字段名进行了输出。

    getFields():获取全部权限修饰符修饰的字段
    Field Name = age
    Field Name = name
    Field Name = height
    Field Name = school

    第四个方法中,我们依据方法名,获取到详细某一个方法,然后传入參数。利用invoke进行方法的调用。

    再调用之前,必须设置method.setAccessible(true);从而能够调用使用private修饰的方法。

    除了上面代码中,用到的这些方法,Class类还有非常多其它的方法。很多其它详细的使用,还是看文档去吧。




    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    express学习
    安装MongoDB步骤
    js事件流
    关于html,css,js三者的加载顺序问题
    重写JS的鼠标右键点击菜单
    深入JS原型与原型链
    eureka学习(二)
    eureka学习(一)
    mysql学习-explain中的extra
    mysql学习-explain
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4713697.html
Copyright © 2020-2023  润新知