`

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反射机制详解

    ### Java反射机制详解 #### 一、反射机制是什么 反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以...

    java面向对象基础、高级pdf讲义

    Java面向对象基础与高级知识点详解 Java是一种广泛使用的面向对象编程语言,它的设计哲学是“一切皆对象”。本讲义将全面深入地介绍Java面向对象的基础概念和高级特性,帮助开发者从初学者到精通者逐步提升技能。 ...

    JAVA反射详解

    ### JAVA反射详解 Java反射是Java编程语言的一个强大特性,允许程序在运行时检查和操作类、接口、字段和方法等。本文章旨在深入解析Java反射机制,包括其原理、应用以及常见用法。 #### 了解Class对象 在Java中,...

    Java Reflection (JAVA反射)详解

    Java 反射(Reflection)是Java编程语言的一个重要特性,它允许程序在运行时动态地获取类的信息(如类名、方法、字段等)并直接操作对象的内部属性。这为开发者提供了强大的灵活性,能够在不预先知道具体类的情况下...

    Java 反射详解

    Java反射是Java编程语言中的一个强大特性,它允许运行时的程序访问并操作类、接口、字段和方法等对象,即使这些对象在编译时并未被明确地引用。这一特性使得Java具有高度的动态性,使得代码能够在运行时检查类的信息...

    Java2编程详解

    2. **面向对象编程**:Java是完全面向对象的语言,它支持类、对象、封装、继承、多态等面向对象特性。理解类和对象的概念,学会如何设计和实现类,以及掌握继承和多态的应用,对于编写可维护、可扩展的代码至关重要...

    Java2编程详解.rar

    1. **面向对象编程**:Java是一种完全面向对象的编程语言,支持类、接口、继承、封装和多态等概念。理解这些基础是学习Java的起点。 2. **类和对象**:Java中的所有代码都基于类,类是创建对象的蓝图。了解如何定义...

    java2编程详解(special_edition_using_java)4.rar

    总之,《Java2编程详解》是一本全面覆盖Java编程的指南,不仅包含基本语法和面向对象设计,还深入讲解了高级主题如并发、网络和反射,对于任何想要深入学习Java的人来说都是一份宝贵的资源。通过学习本书,读者将...

    最新Java 编程详解

    1. **Java语言基础**:从变量、数据类型、运算符、流程控制语句(如if-else、switch、for、while)到类、对象、封装、继承和多态等面向对象编程的基本概念。 2. **集合框架**:Java集合框架是处理对象数组的重要...

    Java开发详解.zip

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

    李兴华系列–JAVA详解视频教程

    根据提供的文件信息,“李兴华系列–JAVA详解视频教程”,我们可以从中提炼出一系列与Java编程语言相关的知识点。尽管部分内容提供了一个百度网盘链接但未给出具体教程内容,这里将基于标题、描述和标签来展开讨论...

    java2编程详解(special_edition_using_java)

    2. **类与对象**:阐述面向对象编程的基本原理,包括类的定义、对象的创建与销毁、封装、继承和多态等概念。 3. **数组与集合框架**:介绍如何使用数组存储和操作数据,并深入探讨Java的集合框架,如ArrayList、...

    java教程 第七课 面向对象的高级特性

    ### Java面向对象高级特性详解 #### 一、静态特性(static) **静态修饰符static**在Java中扮演着至关重要的角色,它允许某些类成员在类级别而非对象级别上进行共享。具体而言: 1. **静态属性(类变量)**:这类...

    Java基础面试题详解与解析-涵盖Java概述、JDK/JRE/JVM、数据类型、面向对象等核心内容

    91道.pdf》涵盖了Java的基础知识点,包括Java概述、JDK/JRE/JVM的区别、Java的跨平台性、数据类型、面向对象编程、类与对象、访问修饰符、运算符、内部类、方法重载与重写、对象相等判断、IO流、反射机制等内容。...

    java反射机制详解与应用.pdf

    Java 反射机制详解与应用 Java 反射机制是一种非常强大的动态相关机制,允许 Java 程序在运行时加载、探知、使用编译期间完全未知的类别。这种机制允许程序在运行时透过 Reflection APIs 取得任何一个已知名称的...

    core java 详解

    理解封装、继承和多态这三大面向对象特性是Java学习的关键。 在类和对象的基础上,文档可能还会介绍接口和抽象类,它们用于实现不同类之间的交互和规范。接口定义了方法签名,强制实现类去实现这些方法,而抽象类...

Global site tag (gtag.js) - Google Analytics