Java总结——反射专题

反射入门详解

引言:反射很多人说很难,其实很简单,就是一般类的应用(个人愚见),如果你对此感兴趣,请认真读完,你就会发现反射入门很简单。

反射是Java的一个特性,其实也是一种面向对象思想的一个深入体验。
类是事物的抽象,类也可以看成class文件。既然是文件那就一个事物,我们就可以把它抽象成类。换一句话说,反射(Class类)就是把类抽象成一个类。可能有点不好懂,看完下一段就懂了。
类就具有属性和方法,很好理解。那么我们做反射这个类(以后用Class类表示)。就需要有个一两个字段,Field和Method(属性和方法),属性是一个复杂的事物,它有修饰符,类型,名称。那么我们把它也抽象成一个类Field。方法同理。也有修饰符、返回值类型、方法名、方法参数。这就抽象成Method类。其中的修饰符(Modifer)、返回值类型(ReturnType)等等,这些自然也抽象成一个个类。
        读到这里是不是很好理解了。
剩下的就和一般的类使用相同了,先写一个事例,来熟悉一下这里面的方法。事例目的反射出一个对象的各种东西。然后我再写一下,他们中的属性使用和方法使用。(熟悉的可以跳过这段代码)
/**
 * @(#)Test.java
 * Description:	TODO 填写文件作用简要说明
 * Version :	0.0.0
 * Copyright:	Copyright (c) 哈尔滨甲骨文培训基地  版权所有
 * Create by:	刘东赫  2015年8月12日
 */
package com.ldh.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射——破解实例
 * 
 * @author 刘东赫
 */
public class Test {
	public static void main(String[] args) {
		try {
			ref();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void ref() throws Exception {

		Class
    
     clazz = Class.forName("com.ldh.domain.User");
		StringBuilder sb = new StringBuilder();
		if (!clazz.isInterface()) {
			System.out.println("类");
			// 头信息
			sb.append(Modifier.toString(clazz.getModifiers())).append(" ");//获得修饰符
			sb.append(clazz.getSimpleName()).append("{\n");//获得简单的类名,没有包名的
			// 属性信息
			Field[] fields = clazz.getDeclaredFields();//获取所有属性包括私有
			//遍历属性集合,得到每个属性的类型和名称
			for (Field fd : fields) {

				sb.append("\t").append(Modifier.toString(fd.getModifiers()));
				sb.append(" ");
				sb.append(fd.getName()).append(";");
				sb.append("\n");

			}
			//构造方法获取
			Constructor
    
    [] cs = clazz.getConstructors();
			//遍历构造方法
			for (Constructor
    
     m : cs) {
				sb.append("\t").append(Modifier.toString(m.getModifiers()));
				sb.append(" ").append(clazz.getSimpleName());

				sb.append("(");

				Class
    
    [] par = m.getParameterTypes();
				int i = 0;
				for (Class
    
     p : par) {
					sb.append(p.getSimpleName() + " ");
					sb.append("arg" + i + ",");
					i++;
				}
				if (par.length != 0)
					sb.deleteCharAt(sb.length() - 1);
				sb.append(") {}").append("\n");
			}

			// 获取方法
			Method[] ms = clazz.getDeclaredMethods();
			//遍历方法
			for (Method m : ms) {
				sb.append("\t").append(Modifier.toString(m.getModifiers()));
				sb.append(" ").append(m.getReturnType().getSimpleName());
				sb.append(" ").append(m.getName()).append("(");
				Class
    
    [] par = m.getParameterTypes();
				int i = 0;
				for (Class
    
     p : par) {
					sb.append(p.getSimpleName() + " ");
					sb.append("arg" + i + ",");
					i++;
				}
				if (par.length != 0)
					sb.deleteCharAt(sb.length() - 1);
				sb.append(")").append("\n");

			}

			sb.append("\n}");

			System.out.println(sb.toString());
		} else {
			System.out.println("接口");
			// 头信息
			sb.append(Modifier.toString(clazz.getModifiers())).append(" ");
			sb.append(clazz.getSimpleName()).append("{\n");
			// 属性信息
			Field[] fields = clazz.getDeclaredFields();
			for (Field fd : fields) {

				sb.append("\t").append(Modifier.toString(fd.getModifiers()));
				sb.append(" ");
				sb.append(fd.getName()).append("=").append(fd.get(fd.getName()));
				sb.append(";");
				sb.append("\n");

			}

			// 获取方法
			Method[] ms = clazz.getDeclaredMethods();
			for (Method m : ms) {
				sb.append("\t").append(Modifier.toString(m.getModifiers()));
				sb.append(" ").append(m.getReturnType().getSimpleName());
				sb.append(" ").append(m.getName()).append("(");
				Class
    
    [] par = m.getParameterTypes();
				int i = 0;
				for (Class
    
     p : par) {
					sb.append(p.getSimpleName() + " ");
					sb.append("arg" + i + ",");
					i++;
				}
				if (par.length != 0)
					sb.deleteCharAt(sb.length() - 1);
				sb.append(") {}").append("\n");
			}

			sb.append("\n}");

			System.out.println(sb.toString());
		}
	}
}
结果:

public User{
	private static final i;
	private name;
	private age;
	public User(int arg0) {}
	public User() {}
	public void find(Object arg0,String arg1)
	public void setName(String arg0)
	public String c()
	public String getName()
	public void setAge(String arg0)
	public String getAge()
	public static void util()


}


好了看完以上的代码,基本用法已经会了:我们在学习一下,怎么使用反射获取对象,使用方法,使用属性。
先将一下理解:方法和属性是不是有对象确定的,就像你的名字是在new了一个人之后才能知道的。方法是动作,也是这个对象(人)产生了以后才知道方法怎么用。
一句话,调用时对象调用,属性方法依赖于对象(静态方法除外)

事例:三种方法为对象设置属性值,只是了解一下方法,不是很好用。
public class Test1 {
	public static void main(String[] args) {
		TUser u = new TUser();
		try {
			new Test1().show1(u, "33");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(u.getName() + "|" + u.getAge());
	}
	
	public void show1(Object obj, String par) throws Exception {
		Class
     
      clazz = obj.getClass();
		//获取属性集合
		Field[] fs = clazz.getDeclaredFields();
		for (Field f : fs) {
			String str = f.getName();
			//拼接字符串也就是set方法名
			String str2 = "set" + str.substring(0, 1).toUpperCase() + str.substring(1);
			//更具名字产生方法
			Method m = clazz.getMethod(str2, String.class);
			m.invoke(obj, par);
		}
	}

	public void show2(Object obj, String par) throws Exception {
		Class
     
      clazz = obj.getClass();
		//获得方法集合
		Method[] me = clazz.getMethods();
		
		for (Method m : me) {
			//有set关键字的设置调用
			if (m.getName().contains("set")) {
				m.invoke(obj, par);
			}

		}
	}

	public void show3(Object obj, String par) throws Exception {
		Class
     
      clazz = obj.getClass();
		Field[] fs = clazz.getDeclaredFields();
		for (Field f : fs) {
			//暴力破解私有属性,直接赋值
			f.setAccessible(true);
			f.set(obj, par);
		}
	}
}
后面会出文章讲解反射异常,和一些反射深入用法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值