当前位置: 首页 > news >正文

Java的动态性支持学习一 - 反射机制 概念概述

Java的动态性支持学习一 - 反射机制 概念概述
Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作
Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制
Java的动态性支持学习四 - 反射调用的性能对比
Java的动态性支持学习五 - 方法句柄 概念和句柄类型
Java的动态性支持学习六 - 方法句柄 获取和调用
Java的动态性支持学习七 - 方法句柄调用的性能对比

反射是Java语言提供的一项非常吸引人的特性,利用反射可以在应用运行时对程序进行动态的控制。

反射技术中用到的特别重要的一个类就是java.lang.Class。Class对象携带类的相应信息,主要包括构造器、方法、成员变量等。其实在Java程序运行过程中,每个类被加载后都在内存中产生一个对应的Class类对象,普通应用程序中这个对象是由系统自己自动维护的,开发者无需关心。

虽然反射为Java提供了动态的能力,但也带来了性能的开销。比如调用同一个方法,使用反射来动态实现比直接在源代码中编写的方式大概慢一到两个数量级,所以请谨慎使用反射。

Class类有几个使用比较频繁的方法:

  • forName(String classname)和 forName(String classname,boolean initialze,ClassLoader loader)
    该方法返回给定串名相应的Class 对象。若给定一个类或接口的完整路径名,那么此方法将试图定位、装载和连接该类。若成功,返回该类对象。否则,抛出 ClassNotFoundException 异常。 例如,下面代码段返回名为java.lang.Thread 的运行 Class 描述器。Class t = Class.forName("java.lang.Thread") ;  此方法是需要指定类加载器的,当用到仅有一个String参数的forName方法时,Class对象将默认调用当前类加载器作为加载器和将第二参数为true。第二个参数说明:如果是false时,调用forName方法只是在命令类加载器载入该类,而不初始化该类的静态区块,只有当该类第一次实例化时,静态区块才被调用。当为true时,则载入时就调用静态区块。
  • getField(String) 获取类的指定名称的public类型属性,包括从祖先类中的继承的。
  • getFields() 获取类的public类型的属性,包括从祖先类中的继承的。
  • getDeclaredFields() 获取类的所有属性,包括public、protected、默认和private访问级别的属性,不包括从祖先类中的继承的。 
  • getMethods() 获取类的public类型的方法。 
  • getDeclaredMethods() 获取类的所有方法。
  • newInstance() 创建类的新实例。 

如果想了解更多可以查看Java doc的Class文档。

获取Class实例的三种方式:

  1. 使用Class类的静态方法forName();
  2. 利用对象调用getClass()方法获取,java.lang.Object专门提供了getClass方法获取对象所在类对应的Class对象;
  3. 使用<类名>.class的方式来获取,这里的class可以看做是类的静态成员,表示执行此类对应的Class对象的引用。对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例;

通过Demo简单示例:

package net.oseye;

import java.lang.reflect.*;

public class ReflectTest {

	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c=Class.forName("net.oseye.User");
//		Class c=User.class;
//		Class c=new User().getClass();
		Field[] fileds=c.getDeclaredFields();
		System.out.print("通过反射获取的属性名:");
		for(Field f:fileds){
			System.out.print(f.getName()+"\t");
		}
		System.out.print("\r\n通过反射获取的方法:");
		for(Method m:c.getMethods()){
			System.out.println(m.toString());
		}
		System.out.print("通过反射获取的构造器:");
		for(Constructor<?> mc:c.getConstructors()){
			System.out.print(mc.getName()+"\t");
		}
	}
}

class User{
	private String name;
	public User(){}
	public User(String name){
		this.name=name;
	}	
	
	public void setName(String name){
		this.name=name;
	}
	public String getName(){
		return this.name;
	}
	
	public void SayHello(String name){
		System.out.println(this.name+" say to "+name+" 'Hello'.");
	}
	
}

输出:

通过反射获取的属性名:name	
通过反射获取的方法:public void net.oseye.User.SayHello(java.lang.String)
public java.lang.String net.oseye.User.getName()
public void net.oseye.User.setName(java.lang.String)
public final native java.lang.Class java.lang.Object.getClass()
public native int java.lang.Object.hashCode()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
通过反射获取的构造器:net.oseye.User	net.oseye.User	

转载于:https://www.cnblogs.com/zhaiqianfeng/archive/2013/01/08/4618274.html

相关文章:

  • 获取GridView行索引
  • win32 多线程基础
  • javascript 跳转页面
  • Java 泛型(一) 泛型使用基础
  • Codeforces 264B Good Sequences ★ (分解素因子+DP)
  • Unity(五):使用场景Ⅱ:用于单例模式
  • 【ZZ】9个offer,12家公司,35场面试,从微软到谷歌,应届计算机毕业生的2012求职之路...
  • 密码绑定至密码文本框中
  • 使用PowerDesigner建立数据库模型
  • outerHTML兼容方法(jquery)
  • 解决compilation debug=true targetFramework=4.0 问题
  • Python学习笔记《Python核心编程》第13章 面向对象编程
  • GDI+ 图片高亮处理
  • int 反射到未知的 Enum , 使用 Enum.ToObject
  • USACO 3.1.1 Agri-Net
  • 3.7、@ResponseBody 和 @RestController
  • CentOS6 编译安装 redis-3.2.3
  • ERLANG 网工修炼笔记 ---- UDP
  • java8 Stream Pipelines 浅析
  • Js基础——数据类型之Null和Undefined
  • Linux快速复制或删除大量小文件
  • MySQL主从复制读写分离及奇怪的问题
  • orm2 中文文档 3.1 模型属性
  • Vim Clutch | 面向脚踏板编程……
  • vue-cli在webpack的配置文件探究
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 构建二叉树进行数值数组的去重及优化
  • 关于使用markdown的方法(引自CSDN教程)
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​什么是bug?bug的源头在哪里?
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • ###C语言程序设计-----C语言学习(6)#
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (C语言)fread与fwrite详解
  • (二)windows配置JDK环境
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (三)docker:Dockerfile构建容器运行jar包
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (一) springboot详细介绍
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET Micro Framework 4.2 beta 源码探析
  • .Net Remoting常用部署结构
  • .NET 自定义中间件 判断是否存在 AllowAnonymousAttribute 特性 来判断是否需要身份验证
  • .NET的微型Web框架 Nancy
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理