java反射 interface_Java反射
1. 介绍
反射是一种能够在程序运行时动态访问、修改某个类中任意属性和方法的机制。
具体:
对于任意一个类,都能够知道这个类的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法和属性
在运行时,当加载完类之后,JVM在堆内存中会自动产生一个Class类型的对象,这个对象包含了完整的类的结构信息
这个Class对象就像一面镜子,透过这个镜子看到类的结构
那么,如何得到这个Class对象呢?以下可否
Class c = new Class();
答案是不行的,因为Class的构造函数定义为私有的,只有JVM可以访问
privateClass(ClassLoader loader) {
classLoader=loader;
}
Class对象获取的三种方式
Class c1 = Code.class;
Class c2=code1.getClass();
Class c3= Class.forName("com.trigl.reflect.Code");
举例
public classTestStudent {public static void main(String[] args) throwsClassNotFoundException {
Student student= new Student(1, "Jack");
Class class1=student.getClass();
Class class2= Student.class;
Class class3= Class.forName("com.example.refs.Student");
System.out.println(class1);
System.out.println(class2);
System.out.println(class3);
}
}
输出
classcom.example.refs.Studentclasscom.example.refs.Studentclass com.example.refs.Student
2. Java反射相关操作
本文以Student类为例:
接口
packagecom.example.refs;public interfaceInterFace {voidread();
}
类
packagecom.example.refs;public class Student implementsInterFace{private intid;publicString name;publicStudent() {}public Student(intid, String name) {this.id =id;this.name =name;
}public void setId(intid) {this.id =id;
}private intgetId() {returnid;
}
@Overridepublic voidread() {}
}
以下具体介绍下具体的用法
2.1 类名称、包名
public classClassName {public static voidmain(String[] args) {
Class> class2 = Student.class;
System.out.println("getSimpleName:" +class2.getSimpleName());
System.out.println("getName:" +class2.getName());
System.out.println("getPackage:" +class2.getPackage());
}
}
输出
getSimpleName:Student
getName:com.example.refs.Student
getPackage:package: com.example.refs
2.2 方法
public Method getDeclaredMethod(String name, Class>...parameterTypes) // 得到本类所有的方法(public/private/proteceted...)public Method getMethod(String name, Class>...parameterTypes) //得到该类所有的public方法,包括父类
举例
public classMethodTest {public static voidmain(String[] args) {
Class> class1 = Student.class;
Method[] methods=class1.getMethods();
Method[] declaredMethods=class1.getDeclaredMethods();for(Method method : methods) {
System.out.println("getMethods: " +method);
}
System.out.println();for(Method method : declaredMethods) {
System.out.println("getDeclaredMethods: " +method);
}
}
}
结果
getMethods: public void com.example.refs.Student.read()
getMethods: public void com.example.refs.Student.setId(int)
getMethods: public final void java.lang.Object.wait() throws java.lang.InterruptedException
getMethods: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
getMethods: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getMethods: public boolean java.lang.Object.equals(java.lang.Object)
getMethods: public java.lang.String java.lang.Object.toString()
getMethods: public native int java.lang.Object.hashCode()
getMethods: public final native java.lang.Class java.lang.Object.getClass()
getMethods: public final native void java.lang.Object.notify()
getMethods: public final native void java.lang.Object.notifyAll()
getDeclaredMethods: public void com.example.refs.Student.read()
getDeclaredMethods: private int com.example.refs.Student.getId()
getDeclaredMethods: public void com.example.refs.Student.setId(int)
指定方法
public classMethodChangeVal {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,
NoSuchMethodException, InvocationTargetException {
Class clazz= Student.class;
Object obj=clazz.newInstance();
Method methodGet= clazz.getDeclaredMethod("getId");
Method methodSet= clazz.getDeclaredMethod("setId", int.class);
methodSet.invoke(obj,123);
System.out.println(methodGet.invoke(obj));
}
}
异常
Exception in thread "main" java.lang.IllegalAccessException: Class
com.example.refs.MethodChangeVal can not access a member of class
com.example.refs.Student with modifiers "private"
原因:setId为私有方法,利用反射时会进行安全检查,用setAccessible(true)不进行安全检查,可以直接对调用私有方法、修改私有变量
public classMethodChangeVal {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,
NoSuchMethodException, InvocationTargetException {
Class clazz= Student.class;
Object obj=clazz.newInstance();
Method methodGet= clazz.getDeclaredMethod("getId");
Method methodSet= clazz.getDeclaredMethod("setId", int.class);
methodGet.setAccessible(true);
methodSet.invoke(obj,123);
System.out.println(methodGet.invoke(obj));
}
}
2.3 构造函数
public Constructor getDeclaredConstructor(Class>... parameterTypes)public Constructor getConstructor(Class>... parameterTypes)
Constructor>[] allConstructors = class1.getDeclaredConstructors();//获取class对象的所有声明构造函数
Constructor>[] publicConstructors = class1.getConstructors();//获取class对象public构造函数
Constructor> constructor = class1.getDeclaredConstructor(String.class);//获取指定声明构造函数
Constructor publicConstructor = class1.getConstructor(String.class);//获取指定声明的public构造函数
举例
public classConstuctorTest {public static voidmain(String[] args) {
Class class2= Student.class;
Constructor>[] constructors =class2.getConstructors();for (Constructor>constructor : constructors) {
System.out.println(constructor+ ", Name:" +constructor.getName());
}
}
}
结果
publiccom.example.refs.Student(), Name:com.example.refs.Studentpublic com.example.refs.Student(int,java.lang.String), Name:com.example.refs.Student
2.4 成员变量
getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
getFields()获得某个类的所有的公共(public)的字段,包括父类。
举例
public classFieldTest {public static voidmain(String[] args) {
Class> aClass = Student.class;
Field[] declardFields=aClass.getDeclaredFields();
Field[] fields=aClass.getFields();for(Field field : declardFields) {
System.out.println("declaredField: " +field);
}
System.out.println();for(Field field : fields) {
System.out.println("field: " +field);
}
}
}
结果
declaredField: private intcom.example.refs.Student.id
declaredField:publicjava.lang.String com.example.refs.Student.name
field:public java.lang.String com.example.refs.Student.name
2.5 修饰符
举例
public classModifierTest {public static voidmain(String args[]) {
Class aClass= Student.class;int modifier =aClass.getModifiers();
System.out.println("modifier:" +modifier);
System.out.println(String.format("isAbstract: %s", Modifier.isAbstract(modifier)));
System.out.println(String.format("isPublic: %s", Modifier.isPublic(modifier)));
System.out.println(String.format("isStatic: %s", Modifier.isStatic(modifier)));
System.out.println(String.format("isFinal: %s", Modifier.isFinal(modifier)));
System.out.println(String.format("isSynchronized: %s", Modifier.isSynchronized(modifier)));
}
}
结果
modifier:1isAbstract:falseisPublic:trueisStatic:falseisFinal:falseisSynchronized:false
2.6 父类
public classGetParent {public static voidmain(String[] args) {
Class class2= Student.class;
System.out.println(class2.getSuperclass());
}
}
结果
class java.lang.Object
2.7 接口
public classInterfaceTest {public static voidmain(String[] args) {
Class> clazz = Student.class;
Class>[] inters =clazz.getInterfaces();for(Class>classIn : inters) {
System.out.println(classIn);
}
}
}
输出
interface com.example.refs.InterFace
2.8 创建对象实例
举例用2种方法创建
public classNewInstanceTest {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,
NoSuchMethodException, InvocationTargetException {
Class clazz= Student.class;
Object obj=clazz.newInstance();
Constructor> constructor =clazz.getDeclaredConstructor();
Object obj2=constructor.newInstance();
Constructor> constructor2 = clazz.getDeclaredConstructor(int.class, String.class);
Object obj3= constructor2.newInstance(1, "HanMeimei");
System.out.println(obj);
System.out.println(obj2);
System.out.println(obj3);
}
}
结果
2.9 注解
自定义一个注解
@Retention(RetentionPolicy.RUNTIME)
@interfaceMyAnnotation {publicString name();public String value();
注:RetentionPolicy.RUNTIME 这个表示运行期注解,这样在反射的时候才能取到
举例
public classAnnotationTest {
@MyAnnotation(name="someName", value = "Hello World")public voiddoSomething() {
}
@Deprecatedpublic voiddelFunc() {
System.out.println("Hello");
}public static void main(String[] args) throwsNoSuchMethodException {
Class clazz= AnnotationTest.class;
Method method= clazz.getMethod("doSomething");
Annotation[] declaredAnnotations=method.getDeclaredAnnotations();for(Annotation annotation : declaredAnnotations) {if (annotation instanceofMyAnnotation) {
MyAnnotation myAnnotation=(MyAnnotation)annotation;
System.out.println("name:" +myAnnotation.name());
System.out.println("value:" +myAnnotation.value());
}else{
System.out.println(annotation);
}
}
}
}
结果
name:someName
value:Hello World
2.10 泛型
参数类型、返回值类型举例
public classGenericTest {public void test01(Map map, Listlist) {
System.out.println("test01");
}public Maptest02() {
System.out.println("test02");return null;
}public static void main(String[] args) throwsNoSuchMethodException {
Method method= GenericTest.class.getMethod("test01", Map.class, List.class);
Type[] types=method.getGenericParameterTypes();for(Type type : types) {
System.out.println("#:" +type);if (type instanceofParameterizedType) {
Type[] genericType=((ParameterizedType)type).getActualTypeArguments();for(Type ontGenericType : genericType) {
System.out.println("泛型类型:" +ontGenericType);
}
}
}
Method method2= GenericTest.class.getMethod("test02");
Type returnType=method2.getGenericReturnType();
System.out.println("\nReturntype" +returnType);if (returnType instanceofParameterizedType) {
Type[] genericTypes=((ParameterizedType)returnType).getActualTypeArguments();for(Type type : genericTypes) {
System.out.println("返回值,泛型类型:" +type);
}
}
}
}
结果
#:java.util.Map
泛型类型:class java.lang.String
泛型类型:class com.example.refs.Student
#:java.util.List
泛型类型:class com.example.refs.Student
Returntypejava.util.Map
返回值,泛型类型:class java.lang.Integer
返回值,泛型类型:class com.example.refs.Student
2.11 数组
public classArrayTest {public static voidmain(String[] args) {int[] intArray = (int[])Array.newInstance(int.class, 3);
Array.set(intArray,0, 123);
Array.set(intArray,1, 124);
Array.set(intArray,2, 125);for (int i = 0; i < Array.getLength(intArray); ++i) {
System.out.println(String.format("array[%s]:%s", i, Array.get(intArray, i)));
}
Class aClass=intArray.getClass();
System.out.println("intArray是否是数组类型:" +aClass.isArray());
System.out.println("intArray成员类型:" +aClass.getComponentType());
}
}
结果
array[0]:123
array[1]:124
array[2]:125
intArray是否是数组类型:true
intArray成员类型:int
3. 分析
3.1 使用场景
操作因访问权限限制的属性和方法
实现自定义注解
动态加载第三方jar包
按需加载类,节省编译和初始化APK的时间
3.2 优缺点
优点:灵活、自由度高:不受类的访问权限限制
缺点
性能问题:通过反射访问、修改类的属性和方法时会远慢于直接操作,但性能问题的严重程度取决于在程序中是如何使用反射的。如果使用得很少,不是很频繁,性能将不是问题
安全性问题:反射可以随意访问和修改类的所有状态和行为,破坏了类的封装性,如果不熟悉被反射类的实现原理,随意修改可能导致潜在的逻辑问题
兼容性问题:因为反射会涉及到直接访问类的方法名和实例名,不同版本的API如果有变动,反射时找不到对应的属性和方法时会报异常
3.3 说明
通过反射访问方法比实例慢很多
有用到反射的类不能被混淆
反射存在性能问题,但使用不频繁、按需使用时,对程序性能影响并不大
反射存在安全性问题,因为可以随意修改类的所有状态和行为(包括private方法和实例)
使用反射访问Android的API时需要注意因为不同API版本导致的兼容性问题
3.4 性能对比
不使用反射、启用安全检查、启用安全检查进行对比
public classTestReflect {
@Testpublic voidtestNoneReflect() {
Student oneStudent= new Student(1, "HanMeimei");long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { oneStudent.setId(1); }long count = System.currentTimeMillis() -start;
System.out.println("没有反射, 共消耗 毫秒");
}
@Testpublic void testNotAccess() throwsClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,
InvocationTargetException {
Student oneStudent= new Student(1, "HanMeimei");
Method method= Class.forName("com.example.refs.Student").getMethod("setId", int.class);long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { method.invoke(oneStudent, 1); }long count = System.currentTimeMillis() -start;
System.out.println("启用安全检查, 共消耗 毫秒");
}
@Testpublic void testUseAccess() throwsClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Student oneStudent= new Student(1, "HanMeimei");
Method method= Class.forName("com.example.refs.Student").getMethod("setId", int.class);
method.setAccessible(true);long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { method.invoke(oneStudent, 1); }long count = System.currentTimeMillis() -start;
System.out.println("取消安全检查, 共消耗 毫秒");
}
}
结果对比
差异
耗时(ms)
没用反射
952
取消安全检查
4283
启用安全检查
14892
原文:http://www.cnblogs.com/kaituorensheng/p/7398069.html
java反射 interface_Java反射相关推荐
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- Java中为什么需要反射?反射要解决什么问题?
Java中为什么需要反射?反射要解决什么问题? 参考文章: (1)Java中为什么需要反射?反射要解决什么问题? (2)https://www.cnblogs.com/buoge/p/9285142. ...
- JAVA基础--JAVA中的反射机制详解
JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能 ...
- java 反射 ppt_Java反射的基本使用
这里是修真院后端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析后端知识/技能,本篇分享的是: [Java反射的 ...
- Java 学习笔记 反射与迭代器
反射 使用反射获得Class类 Class cls = Class.forName("全类名") //包括包名 Class cls = xx.Class;//xx代表类名 Clas ...
- Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...
反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...
- java f反射_java反射机制
反射定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- java 有哪些反射机制_Java 的反射机制你了解多少?
不知道多少次听说过了Java反射机制的使用,比如:Spring 框架如何实例化IoC容器中的Bean,编码过程中如何动态的清理对象中的字段信息等等.工作中只是听说.看同事们编码实践,但是自己却只是概念 ...
- Java 中使用反射来创建对象、调用方法
Java 中使用反射来创建对象.调用方法 反射创建对象 反射调用方法 反射调用私有方法 反射调用可变参私有方法 反射调用的方法自身可以抛出异常的情形 假设已有下面的类: import java.l ...
最新文章
- 使用jQuery for Asp.Net 我的开发环境配置
- 解决AttributeError: module ‘cv2.cv2‘ has no attribute ‘estimateRigidTransform‘
- 数据中心调试的重新思考
- 汉仪尚巍手书可以商用吗_【商用车维修】夏天修空调可以撑起全年修车收入的一半,你会了吗?...
- ffmpeg.exe 笔记
- 启明星辰集团DT总部落地杭州 数据绿洲版图驱动未来发展
- 详解javascript的bind方法
- linux centos7.9图形界面版本下载_适合在任何地方使用的 Linux:15 个小型 Linux 发行版...
- 数值分析与算法——读书笔记(一)
- 增粉的各种方法【微信 / 微博 增加粉丝的108种方法】
- Notepad++的字体设置加Consolas和微软雅黑混合字体
- JavaScript知识点全面概括与总结(上)
- smart 支持标签
- 桌面最前 desk_使用T3Desk在3D桌面环境中管理应用程序
- vue 打包之后不兼容ie_vue项目打包后在IE浏览器报错,页面显示空白
- 【STM32F4系列】【HAL库】旋转编码器(EC11)
- 从思维转变看数字化转型 IT 经营
- GBase UP是做什么的
- PS2019计算机丢失,小编教您ps2019中如何调出历史记录
- Cisco之show ip arp 与 show mac-address-table
热门文章
- 清华大学环境工程专业考研经验分享
- 大数据笔试题目练习(附答案)
- surface pro java_微软新发布的Surface Pro与Surface Pro4有什么区别?值得你升级吗?
- unique去重函数
- 女生被逼疯的日记(课余篇)
- leetcode-4.11[1276. 不浪费原料的汉堡制作方案、237. 删除链表中的节点、657. 机器人能否返回原点](python解法)
- 论流氓软件,以及其解决方法。
- 学英语《每日一歌》之take me to your heart
- 码绘让你眼前一新——雪梨的码绘点评Time
- 表格练习(工商银行电子汇款单)表单练习(用户注册)