网站首页 > 技术教程 正文
先说一下Java的内存模型,也就是java虚拟机在运行时的内存。运行时的内存分为线程私有和线程共享两块。
线程私有的有程序计数器,虚拟机栈,本地方法栈,线程共享的有方法区(包含运行时常量池),java堆。
我们平时说的java内存分为堆和栈,分别对应的是上面的堆和虚拟机栈。
程序计数器:java允许多个线程同时执行指令,如果是有多个线程同时执行指令,那么每个线程都有一个程序计数器,在任意时刻,一个线程只允许执行一个方法的代码,每当执行到一条java方法的代码时,程序计数器保存当前执行字节码的地址,若执行的为native方法,则PC的值为undefined。
虚拟机栈:描述了java方法执行的内存模型,每个方法在执行的时候都会创建出一个帧栈,用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每个方法的从调用到完成,都对应着一个帧栈从入栈到出栈的过程。
本地方法栈:为虚拟机使用到的Native方法提供内存空间,本地方法栈使用传统的C Stack来支持native方法。
java堆:提供线程共享时的内存区域,是java虚拟机管理的最大的一块内存区域,也是gc的主要区域,几乎所有的对象实例和数组实例都要在java堆上分配。java堆的大小可以是固定的,也可以随着需要来扩展,并且在用不到的时候自动收缩。
方法区:存放已被虚拟机加载的类信息,常量,静态变量,编译器编译后的代码等数据。
运行时常量池:存放编译器生成的字面量和符号引用。
1.反射是什么
反射是java语言的特性之一,它允许运行中的程序获取自身的信息,并且可以操作类和对象的内部属性。java反射框架主要提供以下功能:
1.在运行时判断任意对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
4.在运行时调用任意一个对象的方法;
2.反射的用途
1.我们在使用ide,输入一个对象,并想调用它的属性和方法的时候,一按点号,编译器就会自动列出它的属性和方法,这里就会用到反射。
2.通用框架,很多框架都是配置化的(比如Spring通过xml配置Bean或者Action), 为了保证框架的通用性,可能需要根据不同的配置文件加载不同的对象或者类,调用不同的方法,这个时候就需要反射,运行时动态加载需要加载的对象。
3.反射的基本运用
上面提到了提供的一些功能,获取类,调用类的属性或者方法。
3.1.获取类(Class)对象
方法有三种:
使用Class的静态方法
直接获取一个对象的Class
调用某个对象的getClass方法
3.2.判断是否为某个类的实例
一般我们使用instanceof,也可以使用Class.isInstance(obj)。
3.3.创建实例
用反射来生成对象的方式主要有两种。
使用Class.newInstance方法
这个方法最终调用的是无参数的构造函数,所以如果对象没有无参数的构造函数就会报错了。使用newInstance必须要保证:1、这个 类已经加载;2、这个类已经连接了。newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。当然构造方法不能是私有的。
先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。当然构造方法不能是私有的。
3.4.获取方法(Method)
获取某个Class对象的方法集合,主要有以下几种方法。
可以获取自身的公有,保护,默认,私有的方法,但是不包括继承实现的方法。
可以获取公有和继承实现的方法。
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
可以获取特定的自身的公有,保护,默认,私有的方法,但是不包括继承实现的方法。
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
可以获取特定的公有和继承实现的方法。
3.5.获取构造器信息(Constructor)
通过Class对象的getConstructor方法。
3.6.获取成员变量信息(Field)
主要是这几个方法,在此不再赘述:
getFiled: 访问公有的成员变量
getDeclaredField:所有已声明的成员变量。但不能得到其父类的成员变量
getFileds和getDeclaredFields用法同上(参照Method)
3.7.调用方法(invoke)
当我们从类中获取了一个方法后,我们就可以用invoke()方法来调用这个方法。
invoke方法用来在运行时动态地调用某个实例的方法。invoke方法会首先检查AccessibleObject的override属性的值。AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。override的值默认是false,表示需要权限调用规则,调用方法时需要检查权限;我们也可以用setAccessible方法设置为true,若override的值为true,表示忽略权限规则,调用方法时无需检查权限(也就是说可以调用任意的private方法,违反了封装)。
3.8.利用反射创建数组
数组在Java里是比较特殊的一种类型,它可以赋值给一个Object Reference。
3.9.泛型的处理
Java 5中引入了泛型的概念之后,Java反射API也做了相应的修改,以提供对泛型的支持。由于类型擦除机制的存在,泛型类中的类型参数等信息,在运行时刻是不存在的。JVM看到的都是原始类型。
4.反射的优化
4.1.善用API
比如,尽量不要getMethods()后再遍历筛选,而直接用getMethod(methodName)来根据方法名获取方法。
4.2.缓存大法好
比如,需要多次动态创建一个类的实例的时候,有缓存的写法会比没有缓存要快很多。还有将反射得到的method/field/constructor对象做缓存。
为什么?当然是因为forName太耗时了。Cache请自行实现。
4.3.尽量使用高版本JDK
4.4.使用反射框架
例如joor,或者Apach](https://github.com/jOOQ/jOOR),或者Apach) Commons BeanUtils,JAVAASSIST。
4.5.ReflectASM通过字节码生成的方式加快反射速度
ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
java的源码在源代码和编译后的类中表现是不一样的。
下面列出java类型对应的类型描述符:
字段描述符示例
方法描述符示例
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群346942462,我们一起学Java!
- 上一篇: 面向对象的六大原则——让代码更优美
- 下一篇: 简单 Java 类 简单java类的设计
猜你喜欢
- 2024-10-02 深入浅出经典java架构设计方法 深入浅出经典java架构设计方法
- 2024-10-02 JAVA中的单例模式 java单例模式有几种
- 2024-10-02 IT技术交流:Java 轻量级整合开发 java轻量化ide
- 2024-10-02 java中的单例模式 java中的单例模式代码
- 2024-10-02 Java内部类浅析 java内部类的类型
- 2024-10-02 java基础数据结构分析 java 基础数据结构
- 2024-10-02 一个简单的Swing窗口程序——Java
- 2024-10-02 Java妹子与数据库老头之间的交流 java与数据库的连接怎么实现
- 2024-10-02 Java初学笔记-分享交流 java初学者教程视频
- 2024-10-02 好用到爆的 Java 技巧 java小技巧
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- sd分区 (65)
- raid5数据恢复 (81)
- 地址转换 (73)
- 手机存储卡根目录 (55)
- tcp端口 (74)
- project server (59)
- 双击ctrl (55)
- 鼠标 单击变双击 (67)
- debugview (59)
- 字符动画 (65)
- flushdns (57)
- ps复制快捷键 (57)
- 清除系统垃圾代码 (58)
- web服务器的架设 (67)
- 16进制转换 (69)
- xclient (55)
- ps源文件 (67)
- filezilla server (59)
- 句柄无效 (56)
- word页眉页脚设置 (59)
- ansys实例 (56)
- 6 1 3固件 (59)
- sqlserver2000挂起 (59)
- vm虚拟主机 (55)
- config (61)
本文暂时没有评论,来添加一个吧(●'◡'●)