前言
一句话概括重要性:几乎所有的框架底层都是用反射来实现的!
一、概述
动态语言: 是一类在运行时可以改变其结构得语言,通俗点说就是在运行时代码可以根据某些条件改变自身结构。
主要动态语言:Object-C、C#、JavaScript、PHP、Python等
静态语言: 与动态语言相对应得,运行时结构不可变的语言就是静态语言。如Java、C、C++
但是Java可以通过反射机制变成 准动态语言 !!!
二、反射机制
反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
1、Java. Reflection
在开发过程中,我们如何用一个对象?
正常方式: 引入需要的”包类“名称 → 通过new实例化 → 取得实例化对象
反射方式: 实例化对象 → getClass()方法 → 得到完整的”包类“名称
这种方式对我们有什么好处和坏处?
优点: 可以实现动态创建对象和编译,体现出很大的灵活性
缺点: 对性能有影响,使用反射基本是一种解释操作,总是慢于正常操作的。
2、获取Class对象的几种方式
①getClass
已知某个类的实例,调用该实例地getClass()方法获取Class对象
首先我们看下万恶之源:
可以看到,这里有个getClass方法,那么Object类有,证明所有的类都应该有这个方法才对!
即:可以通过对象反射求出类的名称。
②类.Class
若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
③forName
已知一个类的全类名,且该类在类路径下,可通过Class类地静态方法forName()获取,可能抛出ClassNotFoundException
④类名.Type
如果是内置基本数据类型可以直接用类名.Type
⑤class.getSuperclass()
利用ClassLoader获取父类的类型。
根据calss对象可以获取到该calss对象的父类的对象!
3、总结:
所有代码如下:
Person person = new Person();
//通过实例化对象获取class对象
Class c1 = person.getClass();
System.out.println("c1 "+c1.hashCode());
//通过类.Class获取class对象
Class c2 = Person.class;
System.out.println("c2 "+c2.hashCode());
//通过forName获取class对象
Class c3 = Class.forName("com.dbright.Java反射.Person");
System.out.println("c3 "+c3.hashCode());
//通过类名.Type
Class c4 = Integer.TYPE;
Class c41 = Integer.class;
System.out.println("c4 "+c4.hashCode());
System.out.println("c41 "+c41.hashCode());
//对象.getSuperclass()
Class c5 = c1.getSuperclass();
System.out.println("c5 "+c5.hashCode());
执行结果如下图:
对于以上的结果,我们可以分为三个部分来看:
1、c1 c2 c3根据三种不同的方式来获取,但是他们的hashCode值是一样的。
2、java的基本类型,可以根据.type方式获取,根据hashCode值来看和.class方式是一样的效果。
3、我们可以获取父类的class对象!
结果:
对象照镜子可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了那些接口。对于每个类而言,JRE都为其保留一个不变的Class类型的对象。
- Class本身也是一个类
- Class对象只能由系统建立对象
- 一个加载的类在JVM中只会有一个Class实例
- 一个Class对象对应的是一个加载到JVM中的一个.class文件
- 每个类的实例都会记得自己是由哪个Class实例所生成
- 通过Class可以完整地得到一个类中地所有被加载的结构
- Class类是Reflection地根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象
4、小拓展
所有类型的Class
//所有类型的Class
public class ReflectionTest{
public static void main(String[] args) {
Class c1 = Object.class; //类 class java.lang.Object
Class c2 = Comparable.class; //接口 interface java.lang.Comparable
Class c3 = String[].class; //一维数组 class [Ljava.lang.String;
Class c4 = int[][].class; //二维数组 class [[I
Class c5 = Override.class; //注解 interface java.lang.Override
Class c6 = ElementType.class; //枚举 class java.lang.annotation.ElementType
Class c7 = Integer.class; //基本数据类型 class java.lang.annotation.ElementType
Class c8 = void.class; //void void
Class c9 = Class.class; //Class class java.lang.Class
//Alt + 左键:全选后复制粘贴
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
//只要元素类型与唯独一样,就是同一个Class
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
}
执行结果如下:
Java注解和反射扩展:Java注解和反射学习汇总
路漫漫其修远兮,吾必将上下求索~
如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧**转载请注明出处哦**
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/17122.html