java反射的学习

今天学习java反射机制:

常见方法

关于反射,常用的有如下一些方法:

clazz.getDeclaredField(name);//获取指定的私有属性
clazz.getField(name);//获取指定的公有属性
clazz.getSimpleName();//获得类名
clazz.getConstructor(parameterTypes);//获取构造函数
clazz.getClassLoader();//获取类加载器
clazz.getComponentType();
clazz.getConstructors();//获取所有的共有的构造方法
clazz.getDeclaredConstructor(parameterTypes);//获取私有的指定参数的构造方法
clazz.getDeclaredFields();//获取所有的属性
clazz.getMethod(name, parameterTypes);//获取指定方法名的方法
clazz.getDeclaredMethods();//获取所有的方法
clazz.getDeclaredMethod(name, parameterTypes);//获取指定方法名的私有方法

运行私有方法

首先新建一个用于反射操作的类People

People.java

public class People {
	
	private void say() {
		System.out.println("=====saysay=======");
		
	}
}
利用反射来运行该方法:

		Class clazz = Class.forName("com.test.refelect.People");
//		Class clazz = new People().getClass();
//		Class clazz = People.class;
		People people = (People) clazz.newInstance();
		Method method = clazz.getDeclaredMethod("say",null);//得到私有的方法
		//需要设置accessible为true否则会抛出
		//can not access a member of class com.test.refelect.People with modifiers "private"
		method.setAccessible(true);
		method.invoke(people, null);//这句代码表示运行people对象的method方法


使用反射操作类属性

进一步,我们给People.java文件中添加如下属性和方法

private String testChangeString = "aaabbbccaaddaa";
	private String fruit;
	private String name;
	private int age;
	private String[]address = new String[3];
	
	public String getFruit() {
		return fruit;
	}

	public void setFruit(String fruit) {
		this.fruit = fruit;
	}

	public People(String name, int age, String[] address) {
		this.name = name;
		this.age = age;
		this.address = address;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String[] getAddress() {
		return address;
	}

	public void setAddress(String[] address) {
		this.address = address;
	}

	public People() {
	}

利用反射运行setName方法:

Method method = clazz.getMethod("setName",String.class)//由于setName是公有的方法,所以这里调用getMethod方法
		method.invoke(people,(Object)(new String("小明")));
		System.out.println(people.getName());
利用反射运行构造函数来new一个实例对象:

Constructor constructor = clazz.getConstructor(String.class,int.class,String[].class);//这里需要传入参数的类型
		//这里需要将所有的参数转换成Object类型
		People people2 = (People) constructor.newInstance(new Object[]{"xiaoming",22,new String[]{"china","shanxi","xi'an"}});
		
		System.out.println(people2.getName()+people2.getAge()+people2.getAddress()[0]+people2.getAddress()[1]+people2.getAddress()[2]);

利用反射将testChangeString属性中的所有a改为b

Field field = clazz.getDeclaredField("testChangeString");
		field.setAccessible(true);
		
		field.set(people,field.get(people).toString().replace('a','b'));
		System.out.println(field.get(people).toString());

利用反射更改属性的值:

	Field fruitField = clazz.getDeclaredField("fruit");
		fruitField.setAccessible(true);
		fruitField.set(people,"apple");
		
		System.out.println(fruitField.get(people));
		
		method = clazz.getMethod("setFruit",String.class);
		method.invoke(people,"banbanba");
		System.out.println(clazz.getMethod("getFruit",null).invoke(people, null));

反射和可变参数

反射和可变参数结合使用,首先在People.java文件中添加如下方法:

private  List<String> getStrings(String a,String b,String ... c) {
		
		List<String>returnStr = new ArrayList<String>();
		returnStr.add(a);
		returnStr.add(b);
		for (int i = 0; i < c.length; i++) {
			returnStr.add(c[i]);
		}
		return returnStr;
	}

利用反射运行发方法如下:

	Class clazz = Class.forName("com.test.refelect.People");
		People people = (People) clazz.newInstance();
		@SuppressWarnings("unchecked")
		Method method = clazz.getDeclaredMethod("getStrings",String.class,String.class,String[].class);
		method.setAccessible(true);
		@SuppressWarnings("unchecked")
		List<String>list = (List<String>) method.invoke(people,new Object[]{"aaaa","bbbb",new String[]{"cccc","dddd","eee","fff"}});
//		System.out.println(list.size());
		for (String string : list) {
			System.out.println(string);
		}

内部类使用反射

下面我创建一个测试类,来演示如何正常或者通过反射实例化内部类,并且运行其中的方法。
People.java
package com.reflect.study;

public class People {
	
	public void sayHello() {
		System.out.println("hello world");
	}
	
	
	class InnerOne {
		
		public void walk() {
			System.out.println("i am walk");
		}
		
	}
	
	// 公有内部类
	public static class InnerTwo {
		public void run() {
			System.out.println("i am running");
		}
	}
	
	// 私有内部类
	private class InnerThree {
		private String name;
		
		public InnerThree(String name) {
			super();
			this.name = name;
		}

		private void stop(String address) {
			System.out.println(name+"is stoping at "+address);
		}
	}
}

创建内部类实例

    这里需要注意的是<font color='red'> 获取内部类构造方法时,需要将其外部类的类对象作为参数传进去,同样实例化内部类时,也需要将外部类对象作为参数传进</ftont>
// 实例化非静态内部类
InnerOne innerOne = new People().new InnerOne();
innerOne.walk();
			
// 实例化公有静态内部类
People.InnerTwo innerTwo = new People.InnerTwo();
innerTwo.run();

===================================================================================================

使用反射方式实例化内部类,并调用其方法
try {
			Class innerOne = Class.forName("com.reflect.study.People$InnerOne");
			Constructor innerOneConstructor = innerOne.getDeclaredConstructor(People.class);
			System.out.println(innerOneConstructor);
			Method walkMethod = innerOne.getDeclaredMethod("walk",null);
			walkMethod.invoke(innerOneConstructor.newInstance(new People()),null);
			
			// public static内部类
		    Class innerTwo = Class.forName("com.reflect.study.People$InnerTwo");
			Method runMethod = innerTwo.getDeclaredMethod("run",null);
			runMethod.invoke(innerTwo.newInstance(), null);
			
			Class innerThree = Class.forName("com.reflect.study.People$InnerThree");
		    Constructor innerThreeConstructor = innerThree.getDeclaredConstructor(new Class[]{People.class,String.class});
		    Method stopMethod = innerThree.getDeclaredMethod("stop",String.class);
		    stopMethod.setAccessible(true);
		    stopMethod.invoke(innerThreeConstructor.newInstance(new Object[]{new People(),"小明"}),"大马路");
			
		} catch (Exception e) {
			e.printStackTrace();
		}




源码下载


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值