浅谈java反射机制

最近总是用到java反射机制,一直不知道其中的原理,通过查阅API以及网络博客,有了一个初步认识,今天抽出时间整理一下,一下示例只是浅谈java反射机制,更深入的学习放在后面。


定义:

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


功能:

Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

Class:

众所周知Java有个Object 类,是所有Java 类的继承根源,其内声明了数个应该在所有Java 类中被改写的方法:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class 对象。
Class 类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象。如果您想借由“修改Java标准库源码”来观察Class 对象的实际生成时机(例如在Class的constructor内添加一个println()),这样是行不通的!因为Class并没有public constructor。

说了一堆概念,下面说一下本文的具体功能实现:

1,实体类

Person.java
package com.superb.reflect;

/**
 * 父类--> 人类
 * @author superb
 *
 */
public class Person {
	/** 姓名 */
	private String name;
	/** 年龄 */
	private int age;
	/** 性别 */
	private String sex;
	/** 手机号 */
	private String phone;
	
	public Person() {
		logger("无参构造方法");
	}
	
	/**
	 * 构造方法
	 * @param name
	 * @param age
	 */
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
		logger("有参构造方法");
	}

	/**
	 * 吃方法
	 * @param date
	 * @param food
	 */
	public void eat(String name, String food){
		logger(name+"开始吃"+food);
	}
	/**
	 * 
	 * @param msg
	 */
	public void logger(String msg){
		System.out.println("----->"+msg);
	}

	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 getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
}package com.superb.reflect;

/**
 * 子类-->学生类
 * @author superb
 *
 */
public class Student extends Person{
	
	/** 学校 */
	private String stuSchool;
	/** 班级 */
	private String stuClass;

	public Student() {
		super();
	}

	public Student(String stuSchool, String stuClass) {
		super();
		this.stuSchool = stuSchool;
		this.stuClass = stuClass;
	}

	public String getStuSchool() {
		return stuSchool;
	}

	public void setStuSchool(String stuSchool) {
		this.stuSchool = stuSchool;
	}

	public String getStuClass() {
		return stuClass;
	}

	public void setStuClass(String stuClass) {
		this.stuClass = stuClass;
	}
}

2,测试类(代码中有详细注解)

package com.superb.junit;


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

import org.junit.Test;

import com.superb.reflect.Person;
import com.superb.reflect.Student;

import junit.framework.TestCase;

/**
 * 测试类
 * @author superb
 *
 */
public class TestReflect extends TestCase{
	
	/**
	 * 通过getCalss方法获取类
	 */
	@Test
	public void testGetClazz() throws Exception{
		Class
     
      clazz = new Person().getClass();
		System.out.println(clazz.getTypeName());
	}
	
	/**
	 * 通过.class属性获取类
	 * @throws Exception
	 */
	@Test
	public void testClass() throws Exception{
		Class
     
      clazz = Student.class;
		System.out.println(clazz.getTypeName());
	}
	
	/**
	 * 通过static method Class.forName() 获取类
	 * @throws Exception
	 */
	@Test
	public void testClazzName() throws Exception{
		Class
     
      clazz = Class.forName("com.superb.reflect.Student");//类的完整路径
		System.out.println(clazz.getTypeName());
	}
	
	
	/**
	 *

可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。

*

JAVA 的Class 类提供了几个方法获取类的属性。

*/ @Test public void testGetClazzField() throws Exception{ //获取类 Class clazz = Student.class; //获取所有属性 Field[] fields = clazz.getDeclaredFields(); for(Field f : fields){ System.out.println("属性名:"+f.getName()+";属性类型:"+f.getType().getSimpleName()); } //获取特定属性 Field field = clazz.getDeclaredField("stuSchool"); System.out.println("属性名:"+field.getName()+";属性类型:"+field.getType().getSimpleName()); //实例化对象 Object obj = clazz.newInstance(); //打破封装类 field.setAccessible(true); //给属性赋值 field.set(obj, "长江师范学院"); System.out.println(field.get(obj)); System.out.println(field.isEnumConstant());//属性是否是枚举 } /** * java通过反射机制得到类对象的方法,并可调用该方法执行操作 * @throws Exception */ @Test public void testGetClazzMethod() throws Exception{ Class clazz = Person.class; //获取所有方法 Method[] methods = clazz.getDeclaredMethods(); for(Method m : methods){ System.out.println("方法名:"+m.getName()+",方法类型:"+m.getReturnType()); if(m.getName().equals("eat")){ Parameter[] params = m.getParameters(); for(Parameter param :params){ System.out.println("参数类型:"+ param.getParameterizedType()); } //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。我们这里调用Person类总的eat方法, m.invoke(clazz.newInstance(), "小明","苹果"); } } } /** * 通过java反射获得类的构造方法,然后调用该构造器创建该类的一个实例 * @throws Exception */ @SuppressWarnings("rawtypes") @Test public void testGetConstructor()throws Exception{ Class clazz = Person.class; // 使用getConstructors获取构造器 Constructor[] constructor1 = clazz.getConstructors(); for(Constructor c : constructor1){ System.out.println(c.getName()); } // 使用getDeclaredConstructors获取构造器 Constructor[] constructor2 = clazz.getDeclaredConstructors(); for(Constructor c : constructor2){ System.out.println(c.getName()); } } }

总结:

下一期将深入讲解java反射机制;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值