javase高级技术

在说反射之前,必须得先说说java的类加载器,类加载器的定义:将.class文件加载到内在中,并为之生成对应的Class对象。

一般有三种

1 Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
2 Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
3 Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径

接下来,我们在说反射

反射的定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。【简单来说 通过class字节码文件来获取他的构造方法,方法和属性的这种技术,叫做反射】

反射的几种用法

在使用反射之前,我们需要获取Class对象

一般有三种方式可以获得

 1类名.class

 2.对象.getClass()

 3.使用Class.forName("类的完整包名"); 推荐使用这种。

通过反射,我们可以获取到类的构造方法,成员变量,成员方法。(包含private的)所以一般为了安全,字节码文件会加密的。

 获取构造方法

 获取构造方法
  getConstructors  //返回构造方法数组
  getDeclaredConstructors //获取私有的构造方法数组
 创建对象
  newInstance()
  con.newInstance(“zhangsan", 20); //有参构造

获取成员变量

 获取所有成员
  getFields,getDeclaredFields
获取单个成员
  getField,getDeclaredField
修改成员的值
  set(Object obj,Object value)    将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

 获取成员方法

获取所有方法
 
 getMethods
  getDeclaredMethods
获取单个方法
  getMethod
  getDeclaredMethod
暴力访问
  method.setAccessible(true); //可以访问私有的

以下是代码

普通java类

package com.demo;

public class Demo {
	private String name;
	private int age;
	public String ssss;

	public Demo(String name) {
		this.name = name;
	}

	public Demo() {

	}

	private Demo(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public void show() {
		System.out.println(name);
	}

	public void showString(String s) {
		System.out.println("s____" + s);
	}

	public String gets(String s) {
		return s;
	}

	@Override
	public String toString() {
		return ("name__" + name + "age__" + age);
	}
}

  测试构造方法【目的是为了实例化对象】

@Test
	public void testConstructor()
	{
		Class<?> dc;
		try {
			dc = Class.forName("com.demo.Demo");
			Constructor[] cons = dc.getConstructors();
			for(Constructor cc:cons)
			{
				System.out.println(cc);  
				//结果如下 
				//public com.demo.Demo()
				//public com.demo.Demo(java.lang.String)
			}
			//获取单个
			Constructor cc = dc.getConstructor(String.class);
			Object ob = 	 cc.newInstance("aaaa");
			System.out.println(ob);
			//获取私有的构造该方法
			Constructor ccint = 	dc.getDeclaredConstructor(int.class);
			ccint.setAccessible(true);//暴力访问
			Object o = ccint.newInstance(111);
			System.out.println(o);	//结果  age__111
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

  测试成员变量以及成员方法

	@Test
	public void testFieldAndMethod() {
		Class<?> dc;
		try {
			dc = Class.forName("com.demo.Demo");
			Field[] fields = dc.getDeclaredFields(); //获取所有的成员变量 包含私有的

			for (Field f : fields) {
				System.out.println(f.toString());
			}
//          结果如下
//			private java.lang.String com.demo.Demo.name
//			private int com.demo.Demo.age
//			public java.lang.String com.demo.Demo.ssss
			Field nameField = dc.getDeclaredField("name");
			// 暴力访问
			nameField.setAccessible(true);
			Constructor cc = dc.getConstructor(String.class);
			Object ob = cc.newInstance("string");
			//赋值语句
			nameField.set(ob, "name test   ");
			System.out.println(ob);  //结果 name__name test   
			//3成员方法  
			Method showStringMethod =  dc.getDeclaredMethod("showString", String.class);
			showStringMethod.invoke(ob, "ssss"); //通过invok执行
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

  

 

原文地址:https://www.cnblogs.com/javabigdata/p/5612972.html