`

Java学习系列(二十)Java面向对象之反射详解

 
阅读更多

 

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45289391

 

前言

今天讲讲Java中的反射。我们常见的反射多用于JDBC中的加载驱动程序Class.forName("com.mysql.jdbc.Driver");、Struts的MVC、Hibernate中的ORM、Spring中的IOC还有一些其他框架等等。那它有什么好处呢?它的好处就是能够动态的创建对象和编译且能够访问某个类中的所有(包括私有)属性方法及对象的属性方法并进行调用,比较灵活,这样也有利于降低类间的耦合度;但反射也有缺点,就是破坏了类的封装性和对象的完整性。

 

 

实例说明

/**
 * 目标类
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @since version 1.0
 * @datetime 2015年4月26日 下午4:50:28
 */

public class Student {
	private String name;
	private Integer age;

	/**
	 * 无参构造并赋默认值
	 */
	public Student() {
		this.name = "张三";
		this.age = 22;
	}

	public Student(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

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

	public void info() {
		System.out.println("做一个快乐的程序员~" + this);
	}

	private void joke() {
		System.out.println("开个玩笑啦。。。");
	}

	// 无参
	public void play() {
		System.out.println(this.name + " is playing...");
	}

	// 重载play
	public void play(String name) {
		System.out.println(this.name + " is playing xx with " + name);
	}

	/**
	 * getClass().getName() + "@" + Integer.toHexString(hashCode());
	 * 推荐实体类都覆写toString方法,方便查看日志信息
	 * 
	 * @return
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

}

目标测试类
/**
 * 利用反射对目标类进行测试
 * 
 * @author [*昨日重现*] lhy_ycu@163.com
 * @since version 1.0
 * @datetime 2015年4月26日 下午5:14:52
 */

public class StudentTest {

	@BeforeClass
	public static void beforeClass() {
		System.out.println("=========在所有测试方法执行前执行--beforeClass=====\n");
	}

	/**
	 * 1、Class.forName("类的完整路径");2、Student.class;3、obj.getClass()
	 * 
	 * @throws Exception
	 */
	@Test
	public void testInfo() throws Exception {
		Class<?> c1 = Class.forName("com.leo.reflection.Student");
		// Class<?> c1 = Student.class;
		// 获取其实例,newInstance()会默认调用无参构造器,因此需要目标类保留无参的构造器
		Student s1 = (Student) c1.newInstance();
		// System.out.println("s1 = " + s1.getClass().getCanonicalName());
		s1.info();
		int age = s1.getAge();
		String name = s1.getName();
		Assert.assertThat(age, Matchers.is(22));// normal
		Assert.assertThat(name, Matchers.is("李四"));// failure
	}

	/**
	 * 通过类的加载器来获取某个类
	 * 
	 * @throws Exception
	 */
	@Test
	public void testInfo2() throws Exception {
		// 获取一个类加载器
		ClassLoader cl = ClassLoader.getSystemClassLoader();
		// 加载指定的类
		Class<?> clazz = cl.loadClass("com.leo.reflection.Student");
		// System.out.println(clazz.getName());
		Student s1 = (Student) clazz.newInstance();
		s1.info();
	}

	/**
	 * 访问构造器
	 * 
	 * @throws Exception
	 */
	@Test
	public void testConstruction() throws Exception {
		Class<?> c1 = Class.forName("com.leo.reflection.Student");
		// 获取带有指定参数列表的构造方法的Constructor对象
		Constructor<?> cs = c1.getDeclaredConstructor(String.class,
				Integer.class);
		Student s1 = (Student) cs.newInstance("小四", 24);
		s1.info();

		// 获取指定类的所有构造器
		// Constructor<?>[] constructors = c1.getDeclaredConstructors();
		// for (Constructor<?> constructor : constructors) {
		// System.out.println("constructor = " + constructor);
		// }
	}

	/**
	 * 访问属性(包括私有属性)
	 * 
	 * @throws Exception
	 */
	@Test
	public void testField() throws Exception {
		Class<?> c1 = Class.forName("com.leo.reflection.Student");
		Student s1 = (Student) c1.newInstance();
		
		// 获取某个属性
		Field field = c1.getDeclaredField("name");
		// 该属性设置为可访问
		field.setAccessible(true);
		System.out.println("field = " + field + " , " + field.get(s1));

		// 获取指定类的所有属性
		// Field[] fields = c1.getDeclaredFields();
		// for (Field f : fields) {
		// f.setAccessible(true);
		// System.out.println(f.getName() + " = " + f.get(s1));
		// }

	}

	/**
	 * 访问方法(包括私有方法)
	 * 
	 * @throws Exception
	 */
	@Test
	public void testMethod() throws Exception {
		Class<?> c1 = Class.forName("com.leo.reflection.Student");
		Student s1 = (Student) c1.newInstance();

		// 获取某个类的指定无参方法
		Method m1 = c1.getDeclaredMethod("play");
		m1.invoke(s1);

		// 获取某个类的指定含参方法
		Method m2 = c1.getDeclaredMethod("play", String.class);
		m2.invoke(s1, "钱七");

		System.out.println("=======================");
		// 获取指定类的所有方法
		// Method[] methods = c1.getDeclaredMethods();
		// for (Method method : methods) {
		// method.setAccessible(true);
		// System.out.println(method.getName());
		// }
		// System.out.println("=======================\n");

	}

	@AfterClass
	public static void afterClass() {
		System.out.println("==========在所有测试方法执行后执行--afterClass=====\n");
	}

}
 
 

总结

1、所有类的对象其实都是Class的实例。
2、Class实例化其他类的对象的时候,一定要保留默认的无参构造函数。
3、加载某个类的3种常用方式:a) Class.forName("类的完整路径")、b) 类名.class、c) obj.getClass()
4、反射的常用的两步:Class<?> c1 = Class.forName("类的完整路径");T1 t = (T1) c1.newInstance();

 

 

分享到:
评论

相关推荐

    Java开发详解.zip

    000000_【课程介绍 —— 写在前面的话】_Java学习概述笔记.pdf 010101_【第1章:JAVA概述及开发环境搭建】_JAVA发展概述笔记.pdf 010102_【第1章:JAVA概述及开发环境搭建】_Java开发环境搭建笔记.pdf 010201_【第2...

    java面向对象之JVM创建及分配策略方法详解.docx

    Java是面向对象的语言,所谓“万事万物皆对象”就是Java是基于对象来设计程序的,没有对象程序就无法运行(8大基本类型除外),那么对象是如何创建的?在内存中又是怎么分配的呢? 正文 一、对象的创建方式 在Java中...

    【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    面向对象基础 Java基本数据类型 string和包装类 final关键字特性 Java类和包 抽象类和接口 代码块和代码执行顺序 Java自动拆箱装箱里隐藏的秘密 Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 ...

    JAVA新手入门 基础面向对象多线编程

    本资料开源与IT开发者 论坛,由创建者:iyangxin 编写,本人只做了整理,如有疑惑请联系原作者。...面向对象 递归 多线程 GUI 反射机制详解 正则表达式 日期处理 字符串 集合 异常处理 IO 流程控制 继承 JAVA高手进阶

    Java基础知识点总结.docx

    五、 封装(面向对象特征之一)★★★★ 23 六、 继承(面向对象特征之一)★★★★ 25 七、 接口(面向对象特征之一)★★★★ 28 八、 多态(面向对象特征之一)★★★★ 30 九、 java.lang.Object 31 十、 异常★...

    Java工程师面试复习指南

    面向对象基础 Java基本数据类型 字符串和包装类 关键字最终特性 Java类和包 抽象类和接口 代码块和代码执行顺序 Java自动拆箱装箱里隐藏的秘密 Java中的Class类和Object类 Java异常 解读Java中的回调 反射 泛型 枚举...

    免费超全面的Java基础类型,容器,并发,IO流,面向对象,Web编程等代码总结

    Java基础类型,容器,并发,IO流,面向对象,Web编程等代码总结。 2、分类文档 JVM虚拟机 JVM特点,结构与执行周期 JVM类加载机制 JVM运行时区数据 JVM执行引擎和垃圾回收 基础语法 理解Java中对象基础Object类 ...

    java高手真经 光盘源码

    javaexception.zip 07.Java面向对象编程扩展(计算器异常捕捉实例) 第3部分(5个程序包) javaio.zip 09.Java输入/输出流 javavi.zip 09.Java输入/输出流上机作业参考(文本编辑器) javathread.zip 10.Java多...

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javaexception.zip 07.Java面向对象编程扩展(计算器异常捕捉实例) 第3部分(5个程序包) javaio.zip 09.Java输入/输出流 javavi.zip 09.Java输入/输出流上机作业参考(文本编辑器) javathread.zip 10.Java多...

    Java高手真经(编程基础卷)光盘全部源码

    javaexception.zip 07.Java面向对象编程扩展(计算器异常捕捉实例) 第3部分(5个程序包) javaio.zip 09.Java输入/输出流 javavi.zip 09.Java输入/输出流上机作业参考(文本编辑器) javathread.zip 10.Java多线程...

    java基础.txt 百度云

    Java 面向对象 深入面向对象和数组 Java 常用类详解 Java 异常机制解析 Java 集合与数据结构 JavaIO 流全解析 深入理解 Java 多线程 Java 网络编程 手动开发一个 Web 服务器 深入理解 Java 注解+反射 Java...

    JAVA SE内容详解

    JAVA SE内容详解,包含数组,数据结构,面向对象,异常处理,注解,泛型,集合,类加载,反射,多线程,IO,网络编程

    java基础案例与开发详解案例源码全

    7.1 面向对象的分析与设计简介180 7.1.1 类的设计建议180 7.1.2 类名.变量名.方法名的选取181 7.1.3 类的属性设计建议182 7.1.4 类的方法设计建议182 7.1.5 继承的设计建议182 7.2 对象模型建立183 7.2.1 UML简介183...

    Java 基础核心总结 +经典算法大全.rar

    continue 语句面向对象 类也是-种对象对象的创建 属性和方法 构造方法 方法重载 方法的重写 初始化 类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限...

    面向对象技术与UML课件及源代码-by 南邮-陈杨

    本书为中南大学精品教材立项项目,分为上下两篇共21章,涵盖了面向对象技术中Java开发环境配置、程序设计基础、面向对象原理以及UML的知识。本书使用的开发环境是JDK 1.6+Eclipse 3.3+Rational Rose 2003,逐步引领...

Global site tag (gtag.js) - Google Analytics