• Java反射


    1. 定义

    JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态

    语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序

    可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。其中,有一个Class类型,

    它是实现反射的起源,针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者唤起为数十多个的Reflection APIs。而关于jvm如何加载类的过程,见文

    2. 实例应用

    案例接口
    public interface China {
    
    	public void sayHello(String name, Integer age);
    }

    案例类
    public class Person implements China{
    
    	private int age;
    	
    	private String name;
    
    	public int getAge() {
    		return age;
    	}
    
    	public final void setAge(Integer age) {
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	@Override
    	public String toString() {
    		return "Person [age=" + age + ", name=" + name + "]";
    	}
    
    	public Person(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	
    	public Person(int age){
    		super();
    		this.age = age;
    	}
    	
    	public Person(String name){
    		super();
    		this.name = name;
    	}
    
    	public Person() {
    		super();
    	}
    
    	@Override
    	public void sayHello(String name, Integer age) {
    		System.out.println("hello "+ name + " : " + age);
    	}
    }


    测试类
    public class ReflectTest {
    
    	/**
    	 * 通过Class.forName和ClassLoader来加载类
    	 * @throws ClassNotFoundException
    	 */
    	@Test
    	public void test1() throws ClassNotFoundException{
    		Class<?> demo1 = null;
    		Class<?> demo2 = null;
    		Class<?> demo3 = null;
    		Class<?> demo4 = null;
    		demo1 = Class.forName("cn.test.reflect.Demo");
    		demo2 = new Demo().getClass();
    		demo3 = Demo.class;
    		demo4 = Demo.class.getClassLoader().loadClass("cn.test.reflect.Demo");
    		System.out.println(demo1.getName());
    		System.out.println(demo2.getName());
    		System.out.println(demo3.getName());
    		System.out.println(demo4.getName());
    	}
    	
    	/**
    	 * 通过Class.forName("").newInstance()生成新对象,调用的是无参构造函数
    	 * @throws ClassNotFoundException
    	 * @throws InstantiationException
    	 * @throws IllegalAccessException
    	 */
    	@Test
    	public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		Person person = (Person) demo.newInstance();
    		person.setAge(12);
    		person.setName("张三");
    		System.out.println(person);
    	}
    
    	/**
    	 * 打印出该类所有的信息:属性,方法,构造函数
    	 * @throws ClassNotFoundException
    	 */
    	@Test
    	public void test3() throws ClassNotFoundException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		System.out.println("类属性");
    		Field[] fields = demo.getDeclaredFields();
    		for(Field field : fields){
    			int mo = field.getModifiers();
    			System.out.print(Modifier.toString(mo)+" ");
    			System.out.print(field.getType().getName()+" ");
    			System.out.print(field.getName());
    			System.out.println();
    		}
    		System.out.println("所有方法");
    		Method[] methods = demo.getDeclaredMethods();
    		for(Method method : methods){
    			Class<?>[] parms = method.getParameterTypes();
    			int mo = method.getModifiers();
    			System.out.print(Modifier.toString(mo)+" ");
    			System.out.print(method.getName()+"(");
    			int i=1;
    			for(Class<?> parm : parms){
    				System.out.print(parm.getName() + " arg"+i++);
    				if(i<=parms.length){
    					System.out.print(",");
    				}
    			}
    			System.out.print(")");
    			System.out.println();
    		}
    		
    		Constructor<?>[] constructors = demo.getConstructors();
    		System.out.print("构造方法:");
    		for(Constructor<?> constructor : constructors){
    			System.out.println();
    			Class<?>[] parms = constructor.getParameterTypes();
    			int mo = constructor.getModifiers();
    			System.out.print(Modifier.toString(mo)+" ");
    			System.out.print(constructor.getName()+"(");
    			int i=1;
    			for(Class<?> parm : parms){
    				System.out.print(parm.getName() + " arg"+i++);
    				if(i<=parms.length){
    					System.out.print(",");
    				}
    			}
    			System.out.print("){}");
    		}
    	}
    	
    	/**
    	 * 获取接口
    	 * @throws ClassNotFoundException 
    	 */
    	@Test
    	public void test4() throws ClassNotFoundException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		Class<?>[] intes = demo.getInterfaces();
    		for(Class<?> interf : intes){
    			System.out.println(interf.getName());
    		}
    	}
    	
    	/**
    	 * 获取父类
    	 * @throws ClassNotFoundException
    	 */
    	@Test
    	public void test5() throws ClassNotFoundException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		Class<?> superClass = demo.getSuperclass();
    		System.out.println(superClass.getName());
    	}
    	
    	/**
    	 * 反射调用类的中任意方法,需要知道方法名
    	 * @throws ClassNotFoundException 
    	 * @throws IllegalAccessException 
    	 * @throws InstantiationException 
    	 * @throws SecurityException 
    	 * @throws NoSuchMethodException 
    	 * @throws InvocationTargetException 
    	 * @throws IllegalArgumentException 
    	 */
    	@Test
    	public void test6() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		Person person = (Person) demo.newInstance();
    		Method sayHelloMethod = demo.getMethod("sayHello", String.class, Integer.class);
    		sayHelloMethod.invoke(person, "张三", 20);
    		
    		Method setAgeMethod = demo.getMethod("setAge", Integer.class);
    		setAgeMethod.invoke(person, 2);
    		
    		Method getAgeMethod = demo.getMethod("getAge");
    		System.out.println(getAgeMethod.invoke(person));
    		
    		Method setNameMethod = demo.getMethod("setName", String.class);
    		setNameMethod.invoke(person, "李四");
    		
    		Method getNameMethod = demo.getMethod("getName");
    		System.out.println(getNameMethod.invoke(person));
    		
    		Method toStringMethod = demo.getMethod("toString");
    		System.out.println(toStringMethod.invoke(person));
    	}
    
    	/**
    	 * 反射设置属性值
    	 * @throws ClassNotFoundException
    	 * @throws InstantiationException
    	 * @throws IllegalAccessException
    	 * @throws NoSuchMethodException
    	 * @throws SecurityException
    	 * @throws IllegalArgumentException
    	 * @throws InvocationTargetException
    	 * @throws NoSuchFieldException 
    	 */
    	@Test
    	public void test7() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException{
    		Class<?> demo = Class.forName("cn.test.reflect.Person");
    		Person person = (Person) demo.newInstance();
    		
    		Field ageField = demo.getDeclaredField("age");
    		ageField.setAccessible(true);
    		ageField.set(person, 10);
    		
    		Field nameField = demo.getDeclaredField("name");
    		nameField.setAccessible(true);
    		nameField.set(person, "王武");
    		
    		System.out.println(person);
    	}
    }
    


  • 相关阅读:
    Redis面试题 总结
    C++ 自由存储区是否等价于堆?(转)
    线程同步方式
    epoll的原理 (一)(转)
    C/C++ 中 volatile 关键字详解(转)
    Linux堆内存管理
    找出数组中出现次数超过一半的数
    剑指offer-复杂链表的复制
    已知二叉树前序中序遍历重建二叉树
    Linux常用命令
  • 原文地址:https://www.cnblogs.com/marcotan/p/4256869.html
Copyright © 2020-2023  润新知