Java 反射,开发框架必备技能

反射一般开发者接触不到,反射主要用户框架的开发。例如我举一个例子你就明白了:

http://www.netkiller.cn/news/list/2.html

通过反射技术我们将上面的统一资源定位付(URL) 映射到Class 相当于

class: news

method: list

parameter: 2

差不多就是下面样子

class News{

public String list(String catagory_id){

...

...

}

}

我们只需要在框架核心中分析 url 然后调用对应的方法,于此同时将参数传递过去。

Class<?> cls = Class.forName("cn.netkiller.reflect.News");
		Object obj= cls.newInstance();
		Method method = cls.getDeclaredMethod("list", int.class);
		return method.invoke(obj, 2);

本文节选自《Netkiller Java 手札》

1.9. Reflection 反射

this.getClass().getName() //当前Class名字
Thread.currentThread().getStackTrace()[1].getMethodName()); //当前方法名	

1.9.1. 获得所有变量

	Field[] fields = objClass.getFields();
	for (Field field : fields) {
		System.out.println(field.getName());
	}			

注意:只能去除 public变量

1.9.2. 批量赋值

1.9.3. 方法操作

JAVA反射调用方法的步骤有三步

得到要调用类的class
得到要调用的类中的方法(Method)
方法调用(invoke)		

1.9.3.1. 获得所有方法

	Class<?> objClass = a.getClass();
	Method[] methods =  objClass.getDeclaredMethods();
	for (Method method : methods) {
		System.out.println(method);
	}			

1.9.3.2. set/get 方法

			package cn.netkiller.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Member {
	public String name;
	private int age;

	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;
	}

	@Override
	public String toString() {
		return "ClassA [name=" + name + ", age=" + age + "]";
	}

	public Member() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class<?> cls = Class.forName("cn.netkiller.reflect.Member");
		Object member = cls.newInstance();
		Method setMethod = cls.getDeclaredMethod("setAge", int.class);
		setMethod.invoke(member, 15);

		Method getMethod = cls.getDeclaredMethod("getAge");
		System.out.println(getMethod.invoke(member));

	}

}			

下面做一个稍微复杂点的例子,ClassB继承ClassA,取出ClassA的成员变量赋值到ClassA。

			package cn.netkiller.reflect;

public class ClassA {
	public String name;
	private int age;

	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 ClassA() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "ClassA [name=" + name + ", age=" + age + "]";
	}
}

package cn.netkiller.reflect;

public class ClassB extends ClassA{

	public ClassB() {
		// TODO Auto-generated constructor stub
	}
	private String address;

	public String getAddress() {
		return address;
	}

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

	@Override
	public String toString() {
		return "ClassB [address=" + address + "]";
	}
	
}


package cn.netkiller.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

	public ReflectionTest() {
		// TODO Auto-generated constructor stub
	}

	public void testSetMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {

		// ClassA a = new ClassA();

		ClassB b = new ClassB();
		b.setAddress("Shenzhen");

		Class<ClassA> classA = ClassA.class;
		ClassA a = classA.newInstance();
		a.setName("Neo");
		a.setAge(30);

		System.out.println(classA.getDeclaredMethod("getAge").invoke(a));

		Method m = classA.getDeclaredMethod("setAge", int.class);
		m.setAccessible(true); // 因为写成private 所以这里必须设置
		m.invoke(b, 26);

		System.out.println(a.toString());
		System.out.println(b.toString());

		System.out.println(b.getName());
		System.out.println(b.getAge());
	}

	public static void main(String[] args) throws InvocationTargetException {

		ReflectionTest rt = new ReflectionTest();
		try {
			rt.testSetMethod();
			
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}			

set 方法

			System.out.println(classA.getDeclaredMethod("getAge").invoke(a));	

get 方法

	Method m = classA.getDeclaredMethod("setAge", int.class);
	m.setAccessible(true);	//因为写成private 所以这里必须设置
	m.invoke(b, 26);	

1.9.3.3. static 方法调用

			Class cls = Class.forName("cn.netkiller.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",int.class);
setMethod.invoke(cls.newInstance(), 15);			

static 方法调用时,不必得实例化对象

			Class cls = Class.forName("cn.netkiller.reflect.Student");
Method staticMethod = cls.getDeclaredMethod("setAge",int.class);
staticMethod.invoke(cls,20); //这里不需要newInstance			

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2016-10-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JAVA技术站

JFinal整合Spring开发 原

思路大概是这样子的,首先需要初始化Spring的容器,把所有注解类加入到容器中,Spring里的AnnotationConfigApplicationConte...

642
来自专栏码字搬砖

java反射的简单使用

前几天项目中遇到一个相对有意思的事情,那就是一个InsertHbase的工具类接收一个对象,然后获取到对象的每一个属性及其值,最后Insert到Hbase中 ...

552
来自专栏用户2442861的专栏

java反射详解

http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html#3143018 (挺牛逼的)...

641
来自专栏java一日一条

Java 动态代理深入解析

要想了解Java动态代理,首先要了解什么叫做代理,熟悉设计模式的朋友一定知道在Gof总结的23种设计模式中,有一种叫做代理(Proxy)的对象结构型模式,动态代...

765
来自专栏微信公众号:Java团长

Java 动态代理深入解析

要想了解Java动态代理,首先要了解什么叫做代理,熟悉设计模式的朋友一定知道在Gof总结的23种设计模式中,有一种叫做代理(Proxy)的对象结构型模式,动态代...

623
来自专栏Hongten

spring开发_BeanFactoryPostProcessor_容器后处理器

http://www.cnblogs.com/hongten/gallery/image/112611.html

701
来自专栏androidBlog

Java 反射机制详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

431
来自专栏JAVA技术站

JFinal 表自动绑定插件实现,实现零配置,支持多数据源

因为java里的属性一般都是驼峰规则,代码看起来舒服一点,这里以数据库中以大写字母为例,表名为T_USER,对应Model名为User实现如下

332
来自专栏java达人

设计模式之代理模式(二)CGLIB动态代理实现

像上一篇所说的代理模式其实是静态代理,在实际开发中其实应用不大,因为他需要事先知道被代理对象是谁,而且被代理对象和代理对象实现了公共的接口。实际情况往往并不能满...

18210
来自专栏吴伟祥

Java中Interface的方法和常量的默认访问修饰符

Java中Interface常量的默认访问修饰符为:public static final 

1263

扫码关注云+社区