Java —— Reflect反射机制
JAVA反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制。
- Java反射的作用?
假如有两个程序员,一个程序员在写程序的时需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码是不能通过编译的。此时,利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。
- Class类的使用
- OOP的世界里,万事万物皆对象。类是谁的对象呢?——类是对象,类是java.lang.Class类的实例对象!There is a class named class.
- 实例:
//有一个类
class Foo {
void print() {System.out.println("Foo");}
} //在main函数里:
public static void main(String[] args) {
//Foo这个类也是一个实例对象,Class类的实例对象,如何表示呢 //任何一个类都是Class类的实例对象,这个实例对象有三种表示方式
//1. --实际在告诉我们,任何一个类都有一个隐含的静态成员变量-class
Class c1 = Foo.class; //2. 已知该类的对象通过getClass 方法
Foo f1 = new Foo();
Class c2 = f1.getClass(); //c1, c2表示了Foo类的类类型(class type)
//指类也是一个对象,是class类的实例对象,这个对象就成为该类的类类型 //不管从c1,c2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
System.out.println(c1 == c2); //true //3.
Class c3 = null;
try {
c3 = Class.forName("com.immoc.reflect.Foo");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(c3 == c2); //true /*
* 我们可以通过类的类类型创建对象实例;
* 通过c1 or c2 or c3创建Foo类的对象
*/
try {
Foo foo = (Foo)c1.newInstance(); //需要有无参的构造方法
foo.print();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}- 动态加载类:例如Class.forName("类的全称")不仅表示了类的类类型,还代表了动态加载类
- 编译时刻加载类是静态加载类、运行时加载类是动态加载
- new 对象是静态加载类,在编译时刻就需要加载所有可能使用到的类
- 动态加载类:
- Class c = Class.forName(args[0]);
- OfficeAble oa = (OfficeAble)c.newInstance(); //通过类类型创建该类的对象实例
- 功能性的类尽量使用动态加载,而非静态加载
- 基本的数据类型,void关键字 都存在类类型
- Class类的基本API操作
/**
* 打印类的信息,包括类的成员函数,成员变量
* @param obj
*/
public static void printClassMessage(Object obj) {
//要获取类的信息,首先要获取类的类类型
Class c = obj.getClass();//传递的是哪个子类的对象,c就是该类的类类型
System.out.println("类的名称是:" + c.getName());
/*
* Method类,方法对象
* 一个成员方法就是一个Method对象
* getMethod()方法获取的是所有public的函数,包括父类继承而来的
*/
Method[] ms = c.getMethods();
for(Method m : ms) {
//得到方法返回值类型的类类型
Class returnType = m.getReturnType();
System.out.print(returnType.getName() + " ");
System.out.print(m.getName() + "(");
//获取参数类型——得到的是参数列表的类型的类类型
Class[] paramTypes = m.getParameterTypes();
for(Class p : paramTypes) {
System.out.print(p.getName() + ",");
}
System.out.println(")");
}
}
- 方法的反射
public static void printMethodMessage(Object obj) {
//要获取类的信息,首先要获取类的类类型
Class c = obj.getClass();//传递的是哪个子类的对象,c就是该类的类类型
System.out.println("类的名称是:" + c.getName());
/*
* Method类,方法对象
* 一个成员方法就是一个Method对象
* getMethod()方法获取的是所有public的函数,包括父类继承而来的
*/
Method[] ms = c.getMethods();
for(Method m : ms) {
//得到方法返回值类型的类类型
Class returnType = m.getReturnType();
System.out.print(returnType.getName() + " ");
System.out.print(m.getName() + "(");
//获取参数类型——得到的是参数列表的类型的类类型
Class[] paramTypes = m.getParameterTypes();
for(Class p : paramTypes) {
System.out.print(p.getName() + ",");
}
System.out.println(")");
}
}- 如何获取某个方法
- 方法的名称和方法的参数列表才能唯一决定某个方法
- 方法反射的操作
- method.invoke(对象,参数列表)
public class MethodDemo1 {
public static void main(String[] args) {
/*
* 要获取print(int, int)方法
* 首先获取类的信息(类的类信息)
*/
A a1 = new A();
Class c = a1.getClass();
//2. 获取方法,名称和参数列表
try {
Method m = c.getDeclaredMethod("print", new Class[]{int.class, int.class});
//方法的反射操作:用对象调用方法
m.invoke(a1, new Object[]{10, 20}); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} class A {
public void print(int a, int b) {
System.out.println(a + b);
}
public void print(String a, String b) {
System.out.println(a.toUpperCase() + "," + b.toLowerCase());
}
}
- 成员变量的反射
- 成员变量也是对象,java.lang.reflect.Field, Field类封装了关于成员变量的操作
- getFields()方法获取的是所有的public的成员变量的信息
- getDeclaredFields()获取的是该类自己声明的所有成员变量的信息
//首先得到类型,然后得到该变量的名称:
//如:private int t;
public static void printFieldMessage(Object obj) {
System.out.println("---------------------------------------------");
Class c = obj.getClass(); Field[] fs = c.getDeclaredFields();
for(Field f : fs) {
//得到成员变量的类型的类类型 :int
Class fieldType = f.getType();
String typeName = fieldType.getName();
//得到成员变量的名称 :t
String fieldName = f.getName();
System.out.println("typeName: " + typeName + " fieldName: " + fieldName);
}
}
- 构造函数的反射
/**
* 打印构造函数的信息(构造函数也是对象:java.long.Constructor)
* @param obj
*/
public static void printConMessage(Object obj) {
Class c = obj.getClass();
Constructor[] cs = c.getDeclaredConstructors();
for(Constructor con : cs) {
System.out.print(con.getName() + "(");
//获取参数列表
Class[] paramTypes = con.getParameterTypes();
for(Class cl : paramTypes) {
System.out.print(cl.getName() + ",");
}
System.out.println(")");
}
}
- Java类加载机制
- 通过反射了解集合泛型的本质
- Java中集合的泛型是防止错误输入的,只在编译阶段有效,编译完之后就无效了。验证:通过方法的反射
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList l1 = new ArrayList();
ArrayList<String> l2 = new ArrayList<String>();
l1.add("hello");
l1.add(2); //wrong?是跟JDK版本有关系嘛???
Class c1 = l1.getClass();
Class c2 = l2.getClass();
System.out.println(c1 == c2); //true,说明编译之后集合的泛型是去泛型化得
//反射的操作都是编译之后的操作 try {
Method m = c2.getMethod("add", Object.class);
m.invoke(l1, "world");
System.out.println(l1.size());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
应用:通过类的名称来生产一个对象 如:Integer in = (Integer) class.forName(className).newInstance();
Java —— Reflect反射机制的更多相关文章
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- Java高新技术 反射机制
Java高新技术 反射机制 知识概要: (1)反射的基石 (2)反射 (3)Constructor类 (4)Field类 (5)Method类 (6)用反射方 ...
- java的反射机制浅谈(转)
原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- 【转】Java利用反射机制访问私有化构造器
Java利用反射机制访问私有化构造器 博客分类: java 我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的. 但是有一种方法可以把带有 ...
- 【转】java原理—反射机制
一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言 ...
- java的反射机制(第三篇)
本文转载自:http://c.biancheng.net/cpp/html/1782.html Person p=new Person();这是什么?当然是实例化一个对象了.可是这种实例化对象的方法存 ...
- java原理—反射机制
http://www.cnblogs.com/forlina/archive/2011/06/21/2085849.html 一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程 ...
随机推荐
- Co. - Microsoft - Windows - Dos命令
DOS命令 cd .. 是进入上一层目录,cd \ 是进入根目录 我们来重申下%~dp0和%cd%的区别, %cd%和%~dp0都能用来表示当前目录,但是他们在不同的使用场景下,功能却不相同: %cd ...
- Ubuntu 配置多域名站点
思路 -- 跟Windows 一样 1添加Nginx 指向项目的入口 配置域名 2修改本地host文件域名指向 实现: 1 进入Nginx 配置文件 默认地址为 /etc/nginx/sites-e ...
- BGP(边界网关协议)简述
BGP的起源 不同自治系统(路由域)间路由交换与管理的需求推动了EGP的发展,但是EGP的算法简单,无法选路,从而被BGP取代. 自治系统:(AS) IGP:自治系统内部协议,ospf,rip,is- ...
- Python3 函数参数
# # 常规参数 # def jiafa(a,b): # print(a+b) # # jiafa(5,6) # # # def xinxi(name,location,sex='male'): # ...
- AES128加密-S盒和逆S盒构造推导及代码实现
文档引用了<密码编码学与网络安全--原理和实践>里边的推导过程,如有不妥,请与我联系修改. 文档<FIPS 197>高级加密标准AES,里边有个S盒构造,涉及到了数论和有限域的 ...
- FireDAC 连接Access (accdb)数据库
FireDAC可以方便连接数据库,但是要连接新版本的accdb数据库,要注意这样的事项(以Office2010版为例) 安装Office2010 x86版,注意,不能安装x64版,因为Delphi I ...
- Spring AOP(一)——基础概念
前文的一些内容更多是针对Spring容器内部的一些特性的描述,接下来一个专题将描述Spring AOP的一些信息,配置细节等等. 介绍 面向切面编程(AOP)是一种新的针对程序结构的思路,它补足了面向 ...
- 责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
本文来自网易云社区 作者:乔安然 1. Chain of Responsiblity 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链 ...
- Java开发WebService(使用Java-WS)
前言: 初学Java,因为工作需要,直接跳到开发WebService.以前用.NET开发过WebService,对比一下,Java的WebService开发部署难度高了不止一个档次.网上的教程各式各异 ...
- Django笔记 —— 基础部分总结
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...