Reflect
反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。简单说:反射技术可以对一个类进行解剖。
反射的好处:大大的增强了程序的扩展性。
反射的基本步骤:
1、获得Class对象,就是获取到指定的名称的字节码文件对象。
2、实例化对象,获得类的属性、方法或构造函数。
3、访问属性调用构造函数创建对象。
、调用方法、获取这个Class对象,有三种方式:
1:通过每个对象都具备的方法getClass来获取。弊端:必须要创建该类对象,才可以调用getClass方法。
2:每一个数据类型(基本数据类型和引用数据类型)都有一个静态的属性class。弊端:必须要先明确该类。
前两种方式不利于程序的扩展,因为都需要在程序使用具体的类来完成。
3:使用的Class类中的方法,静态的forName方法。
指定什么类名,就获取什么类字节码文件对象,这种方式的扩展性最强,只要将类名的字符串传入即可。
// 1. 根据给定的类名来获得 用于类加载
String classname = "cn.itcast.reflect.Person";// 来自配置文件
Class clazz = Class.forName(classname);// 此对象代表Person.class
// 2. 如果拿到了对象,不知道是什么类型 用于获得对象的类型
Object obj = new Person();
Class clazz1 = obj.getClass();// 获得对象具体的类型
// 3. 如果是明确地获得某个类的Class对象 主要用于传参
Class clazz2 = Person.class;
反射的用法:
1)、需要获得java类的各个组成部分,首先需要获得类的Class对象,获得Class对象的三种方式:
Class.forName(classname) 用于做类加载
obj.getClass() 用于获得对象的类型
类名.class 用于获得指定的类型,传参用
2)、反射类的成员方法:
Class clazz = Person.class;
Method method = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});
method.invoke();
3)、反射类的构造函数:
Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2,...})
con.newInstance(params...)
4)、反射类的属性:
Field field = clazz.getField(fieldName);
field.setAccessible(true);
field.setObject(value);
获取了字节码文件对象后,最终都需要创建指定类的对象:
创建对象的两种方式(其实就是对象在进行实例化时的初始化方式):
1,调用空参数的构造函数:使用了Class类中的newInstance()方法。
2,调用带参数的构造函数:先要获取指定参数列表的构造函数对象,然后通过该构造函数的对象的newInstance(实际参数) 进行对象的初始化。
综上所述,第二种方式,必须要先明确具体的构造函数的参数类型,不便于扩展。所以一般情况下,被反射的类,内部通常都会提供一个公有的空参数的构造函数。
------------------------------------------------------
// 如何生成获取到字节码文件对象的实例对象。
Class clazz = Class.forName("cn.itcast.bean.Person");//类加载
// 直接获得指定的类型
clazz = Person.class;
// 根据对象获得类型
Object obj = new Person("zhangsan", 19);
clazz = obj.getClass();
Object obj = clazz.newInstance();//该实例化对象的方法调用就是指定类中的空参数构造函数,给创建对象进行初始化。当指定类中没有空参数构造函数时,该如何创建该类对象呢?请看method_2();
public static void method_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
//既然类中没有空参数的构造函数,那么只有获取指定参数的构造函数,用该函数来进行实例化。
//获取一个带参数的构造器。
Constructor constructor = clazz.getConstructor(String.class,int.class);
//想要对对象进行初始化,使用构造器的方法newInstance();
Object obj = constructor.newInstance("zhagnsan",30);
//获取所有构造器。
Constructor[] constructors = clazz.getConstructors();//只包含公共的
constructors = clazz.getDeclaredConstructors();//包含私有的
for(Constructor con : constructors) {
System.out.println(con);
}
}
------------------------------------------------------
反射指定类中的方法:
//获取类中所有的方法。
public static void method_1() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method[] methods = clazz.getMethods();//获取的是该类中的公有方法和父类中的公有方法。
methods = clazz.getDeclaredMethods();//获取本类中的方法,包含私有方法。
for(Method method : methods) {
System.out.println(method);
}
}
//获取指定方法;
public static void method_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
//获取指定名称的方法。
Method method = clazz.getMethod("show", int.class,String.class);
//想要运行指定方法,当然是方法对象最清楚,为了让方法运行,调用方法对象的invoke方法即可,但是方法运行必须要明确所属的对象和具体的实际参数。
Object obj = clazz.newInstance();
method.invoke(obj, 39,"hehehe");//执行一个方法
}
//想要运行私有方法。
public static void method_3() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
//想要获取私有方法。必须用getDeclearMethod();
Method method = clazz.getDeclaredMethod("method", null);
// 私有方法不能直接访问,因为权限不够。非要访问,可以通过暴力的方式。
method.setAccessible(true);//一般很少用,因为私有就是隐藏起来,所以尽量不要访问。
}
//反射静态方法。
public static void method_4() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("function",null);
method.invoke(null,null);
}
eg:
package Test01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class TestMain {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
NoteBook noteBook=new NoteBook();
noteBook.open();
File file=new File("C:\\Users\\cc\\Desktop\\usb.properites");
if(!file.exists())
file.createNewFile();
FileInputStream fileInputStream=new FileInputStream(file);
Properties properties=new Properties();
properties.load(fileInputStream);
for(int i=0;i<properties.size();i++){
String className=properties.getProperty("usb"+i);
Class clazz=Class.forName(className);
USB usb=(USB)clazz.newInstance();
noteBook.useUSB(usb);
}
}
}
Reflect的更多相关文章
- C#基础---Attribute(标签) 和 reflect(反射) 应用二
以前我有写过一篇有关,打标签和反射的应用,主要用于类中字段的验证.下面是连接 C#基础---Attribute(标签) 和 reflect(反射) 应用. 这个项目迭代发现公司项目里面发现老代码对业务 ...
- go reflect
package main import ( "fmt" "reflect" // 反射包 ) type User struct{ //结构体类型 Id int ...
- 12,13 Proxy和Reflect
Proxy和Reflect Proxy(代理) Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程 ...
- golang reflect
golang reflect go语言中reflect反射机制.详细原文:地址 接口值到反射对象 package main import ( "fmt" "reflect ...
- C#基础---Attribute(标签) 和 reflect(反射) 应用
1.Attribute的定义与作用: 公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法和属性等.Attributes和Micros ...
- 错误: java.lang.reflect.InvocationTargetException
错误: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(N ...
- 自己写一个java.lang.reflect.Proxy代理的实现
前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...
- ES6新特性:Javascript中的Reflect对象
Reflect介绍: Reflect这个对象在我的node(v4.4.3)中还没有实现, babel(6.7.7)也没有实现 ,新版本的chrome是支持的, ff比较早就支持Proxy和Reflec ...
- java.lang.reflect.Method
java.lang.reflect.Method 一.Method类是什么 Method是一个类,位于java.lang.reflect包下. 在Java反射中 Method类描述的是 类的方法信息, ...
- java.lang.reflect.Constructor
java.lang.reflect.Constructor 一.Constructor类是什么 Constructor是一个类,位于java.lang.reflect包下. 在Java反射中 Cons ...
随机推荐
- html之texteara
定义多行的文本输入控件,所有浏览器都支持,可容纳无限的文本,等宽的字体. 用css的height和width来设置其框框的大小是个很好的办法,其中的文本换行符为%OD/%OA(回车换行) html5中 ...
- setOnKeyListener响应两次问题
1.Android一次按下操作定义了两个事件,ACTION_DOWN和ACTION_UP,即按下和松手两个动作. 2.除了判断是什么按键被按下,还应该判断按键是up还是down 3.调用eve ...
- SQL集合运算参考及案例(二):树形节点数量逐级累计汇总
问题描述: 我们经常遇到这样一个问题,类似于面对一个树形结构的物料数据,需要将库存中每一种物料数量汇总到物料上展示出来:或者说组织机构是一棵树,我们需要统计每一个节点上的人员数量(含下级节点的累计数量 ...
- ActionScript ArrayCollection sort
var sortByOrderId:Sort = new Sort; sortByOrderId.fields = [new SortField("orderId")]; orde ...
- C# Tips: 将 VS2012 / VS2013 的.sln文件、project文件转换成 VS2010格式
原来有一些VS2013的工程文件(.sln..csproj),使用.Net 4.0.现需要将它们转换成VS2010格式. 经实验,办法如下: (1) 在Solution文件(.sln)中: 把文件头部 ...
- Python基础教程【读书笔记】 - 2016/7/14
希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第六波:第2章 列表和元组 [总览] 数据结构,是通过某种方式组织在一起的数据元素的集合,数据元素可以使数字或字符串 ...
- erlang r19里面的mnesia_ext
r19据说支持了mnesia_ext,终于可以给那个恶心2gb limit的mnesia换存储引擎了 先下载r19源码,编译 ./otp_build all -a ~/dev/erlang/r19 . ...
- [系统开发] Squid 认证系统
一.用途 用过 Squid 的用户认证模块的同事一定知道,它有个很麻烦的问题:每过一段时间就会跳出一个重新输入密码的窗口,用户不胜其烦,我查了网上的各种配置资料,始终没有找到一个圆满的解决方法,所以编 ...
- sql server 2012 如何收缩事务日志
sql2008不再支持 BACKUP LOG 数据库名 WITH NO_LOG 语句 BACKUP Log zxta with no_log 截断事务日志 sql2008 提示错误如下 BACKU ...
- div+css之清除浮动
当元素有浮动属性时,会对其父元素或后面的元素产生影响,会出现一个布局错乱的现象,可以通过清除浮动的方法来解决浮动的影响. 浮动的清理(clear): 值:none:默认值.允许两边都可以有浮动对象:l ...