[toc]
1. String类特有的方法
charAt
Return the char value at the specified index of this string.codePointAt
Return the code point value of the character at the specified index.codePointBefore
Return the the Unicode code point value before the given index.codePointCount
Return the number of Unicode code points in the specified text range.offsetByCodePoints
Return the index within this string.getChars
Copy characters from this string into dst starting at dstBegin.getBytes
Copies characters from this string into the destination byte array.contentEquals
Compares this string to the specified StringBuffer or CharSequence.equalsIgnoreCase
Compares this String to another String, ignoring case considerations.compareToIgnoreCase
Compares two strings lexicographically, ignoring case differences.regionMatches
Tests if two string regions are equal.startsWith
Tests if the substring of this string beginning at the specified index starts with the specified prefix.endsWith
Tests if this string ends with the specified suffix.indexOf
Returns the index within this string of the first occurrence of the specified character.indexOfSupplementary
Handles (rare) calls of indexOf with a supplementary character.lastIndexOf
Returns the index within this string of the last occurrence of the specified character.lastIndexOfSupplementary
Handles (rare) calls of lastIndexOf with a supplementary character.substring
Returns a string that is a substring of this string.subSequence
Returns a character sequence that is a subsequence of this sequence.concat
Concatenates the specified string to the end of this string.replace
replaceFirst
replaceAll
split
toLowerCase
toUpperCase
trim
toCharArray
面试时,一般说出几个常用的即可。
2. 静态方法为什么不能调用动态(非静态)方法
因为静态方法是属于类的,随着的类的加载而加载;而动态方法是属于对象,只有对象存在时,动态方法才存在,当对象不存在时,动态方法也不存在。因此静态方法无法调用动态方法。
3. JVM内存结构
3.1 方法区(Method Area)
3.2 虚拟机栈(VM Stack)
虚拟机栈是线程私有的,每个方法执行的时候都会创建一个栈帧(Stack Frame),栈帧用于存储局部变量表、操作数栈、动态链接、方法出口信息等,每个方法从调用开始到结束的过程,都对应这Vm Stack中的入栈出栈的过程
3.2.1 局部变量表
局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量,其中存放的数据的类型是编译期可知的各种基本数据类型、对象引用和返回类型(它指向了一条字节码指令的地址)。局部变量表所需的内存空间在编译期间完成计算的,即在Java程序被编译成Class文件时,就确定了所需分配的最大局部变量表的容量。当进入一个方法时,这个方法需要在栈中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
3.2.2 操作数栈
操作数栈又常被称为操作栈,操作数栈的最大深度也是在编译的时候就确定了。32位数据类型所占的栈容量为1, 64位数据类型所占的栈容量为2。当一个方法开始执行时,它的操作栈是空的,在方法的执行过程中,会有各种字节码指令(比如:加操作、赋值元算等)向操作栈中写入和提取内容,也就是入栈和出栈操作。Java虚拟机的解释执行引擎称为“基于栈的执行引擎”,其中所指的“栈”就是操作数栈。因此我们也称Java虚拟机是基于栈的,这点不同于Android虚拟机,Android虚拟机是基于寄存器的。基于栈的指令集最主要的优点是可移植性强,主要的缺点是执行速度相对会慢些;而由于寄存器由硬件直接提供,所以基于寄存器指令集最主要的优点是执行速度快,主要的缺点是可移植性差。
3.2.3 动态链接
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。Class文件的常量池中存在有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用,一部分会在类加载阶段或第一次使用的时候转化为直接引用(如 final、static 域等),称为静态解析,另一部分将在每一次的运行期间转化为直接引用,这部分称为动态连接。
3.2.4 方法返回地址
当一个方法被执行后,有两种方式退出该方法:执行引擎遇到了任意一个方法返回的字节码指令或遇到了异常,并且该异常没有在方法体内得到处理。无论采用何种退出方式,在方法退出之后,都需要返回到方法被调用的位置,程序才能继续执行。方法返回时可能需要在栈帧中保存一些信息,用来帮助恢复它的上层方法的执行状态。一般来说,方法正常退出时,调用者的PC计数器的值就可以作为返回地址,栈帧中很可能保存了这个计数器值,而方法异常退出时,返回地址是要通过异常处理器来确定的,栈帧中一般不会保存这部分信息。方法退出的过程实际上等同于把当前栈帧出栈,因此退出时可能执行的操作有:恢复上层方法的局部变量表和操作数栈,如果有返回值,则把它压入调用者栈帧的操作数栈中,调整PC计数器的值以指向方法调用指令后面的一条指令。
3.3 堆(Heap)
堆区是所有线程共享的,也是我们大部分的对象的聚居地,也是JVM管理的最大一块内存,也是GC开展工作的主要区域。
堆内存中分为一块区域,用于存储类信息,静态变量等等数据,这一块区域之前叫做方法区后面又叫永久带,之后改名叫做Meta-Area/Meta Space Area,元数据空间。
3.3.1 元数据空间(Meta-Area)
这块区域也是线程共享的区域,它主要存储JVM加载类的类信息,类变量,常量(这个在meta-area的常量区),即时编译器编译后的代码等数据。
3.3.2 运行时常量区
这个区域是Meta-Area的一部分,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
3.4 本地方法栈(Native Method Stack)
该区域与虚拟机栈所发挥的作用非常相似,只是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为使用到的本地操作系统方法服务,比如Java调用c/c++/汇编就用到这块区域。
3.5 程序计数器(Program Counter Register)
程序计数器是线程私有的,记录线程当前执行到了哪一条指令,是Java虚拟机规范中唯一一个没有规定任何内存错误的区域。