1 常用类
应用程序不能创建自己的Runtime实例,但是可以通过Runtime类的静态方法getRuntime()获取与之关联的Runtime对象:Runtime rt=Runtime.getRuntime();
1.1 包装类?
Java是面向对象编程语言 ,提倡万物皆对象。但Java并不完全面向对象,因为巴中基本数据类型不是类。所以他们不具有类的特性(继承、多态和封装等),也不能实例化对象。八种基本数据类型之所以不直接设计成类,原因是为了运行效率考虑。
而Java的设计者一方面想要提高运行效率,一方面还想要Java面向对象的完全性。所以,Java中将八种基本数据类型封装成类,该类成为包装类。所有的基本数据类型都能很方便的与对应的包装类相互装换。程序员可根据开发需要任意选择。
特点: 1、除Character类和Boolean类继承于Object类,其他的包装类都继承于Number类。
2、所有的包装类都是final类型,不能派生子类;
3、实例化包装类对象后,对象中保存的基本数据的值不能改变;
4、包装类封装了基本数据类型的属性(如最大值、最小值等),以及大量的有用的方法(如数据类型转换)
基本数据类型与包装类之间的转换机制:自动装箱和自动拆箱
自动装箱:将基本数据类型包装为对应的包装类对象:
自动拆箱:将包装类对象转换为对应的基本数据类型。
数字类型装箱的特殊:
1)2个Integer对象之间也可以用>、<等符号比较大小(2个包装类对象拆箱后再比较大小)
2)2个INteger对象最好不要用==比较,原因是[-128,127]范围内饰取缓存内对象比较,所以相等;该范围外事2个不同的对象引用比较,所以不等.
注意:不要过度使用自动装箱和自动拆箱功能,因为他们可能会导致程序的性能下降.
1.2 什么是正则表达式?
是一种描述字符集的方法,它是以字符集中各字符串的共有特性为依据。
简单说,正则表达式就是记录字符串所在的规则。
正则表达式的作用是什么?
正则表达式可以用于验证、匹配、搜索、替换和编辑或者操作文本和数据。
正因为如此,正则表达式现在是作为程序员基本技能之一,学习和使用正则表达式在工作中可以达到很高的效率。
java.util.regex包
验证一个或多个汉字:^[\u4e00-\u9fa5]+$
1-12月 0?[1-9]|1[0-2]
1-31天 0?[1-9]|[12][0-9]|3[01]
1.3 String类
string a="abc"和String s=new String("abc");的区别
在JVM虚拟机JVM中存在一个字符串池,其中保存着很多字符串对象,并且可以被共享使用.因此他提高了运行效率.
String a="abc"语句被执行时,JVM首先在字符串池中去查找是否存在值为"abc"的对象,判断依据是String类equals方法的返回值.如果有,则不再实例化新的对象,直接返回已存在对象的引用;如果没有,则创建这个对象,然后把它加入到字符串池,再将其引用返回.
String s=new String("abc")语句,这里的"abc"本身是字符串池中的一个对象,而运行时执行new String()时,将字符串池中的对象复制一份放到堆里,并且把堆中的这个对象的引用返回,所以一共创建了两个对象.这种方式增加了性能开销,所以开发时建议避免使用这种方式.
字符串的特点
1)必须是必须使用引号;
2)字符串的字符使用Unicode国际统一字符编码,一个字符占用2个字节
3)String类是一个final类代表不可变的字符系列
4)字符串是不可变的。一个字符串对象一旦被实例化,他的内容就固定不变。※
String类和intern()方法可以证明字符串是不可变的。
String str="Just";
str="Justion";
如果程序对字符串附加字符串的操作很频繁,并不建议用"+"来进行字符串的串联.
String类的操作方法
1)length 返回字符串的长度
2)charAt(int index)返回index+1位置的字符
3)equalsIgnoreCase忽略大小写比较
4)indexOf(string s)返回指定字符串在此字符串中第一次出现的索引
5)startsWith(string s)测试此字符串是否以制定的前缀开始
6)endsWith(string s)测试此字符串是否以制定的后缀结束
7)subString 获取当前字符串的子串
8)replace替换字符串
9)trim去掉字符串的前后空格
10)concat连接2个字符串
11)split给定正则表达式的匹配来拆分字符串
1.4 String 、StringBuffer和StringBuilder的区别
String类包含了一个不可变的字符串。一旦一个String对象被创建,
包含在这个对象中的内容就是不可改变的,直至这个对象被销毁。
StringBuffer和StringBuilder包含一个可修改的字符串。修改字符串不会实例化新的对象。
StringBuffer是线程安全的,StringBuilder是线程不安全的。
String str="";
StringBuffer temp=new StringBuffer("hello");
temp.append("world");
str=temp.toString();
System.out.println(str);
1.4.1 性能关系
String<StringBuffer<StringBuilder
2 反射类加载和垃圾回收
类的加载机制和执行机制是Java虚拟机(JVM)的两个最主要的功能
2.1 什么是类的加载机制
虚拟机把描述类的数据从class文件(字节码文件)加载到内存,并对数据进行校验、转换、解析和初始化,最终形成可以被直接使用的java类型,这就是虚拟机的类加载机制。
重点:类的生命周期包括加载(loading)、验证(verfication)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、卸载(Unloading)等七个阶段。其中验证、准备和解析三个部分统称为链接(Linking)。
2.1.1 加载阶段:
通过一个类的全限定名(包名+类名)来获取此类的二进制字节流,将这个字节流所代表的静态存储结构转化为方法区的运行时的数据结构,在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。
2.1.2 验证阶段:
不同虚拟机会进行不同类验证的实现,但大致都会完成以下四个阶段的检验过程:文件格式检验(检验字节流是否符合Class文件格式的规范,并能被当前版本的虚拟机处理),字节码的验证(对类方法进行数据流和控制流分析,保证类的方法在运行时不会做出威海虚拟机的行为)和符号引用验证(发生在将符号引用转化为直接引用的时候,在解析阶段中发生)。
2.1.3 准备阶段:
正式为类成员变量分配内存并设置类初始值(通常情况下是数据类型的零值,不进行赋值操作)的阶段,这些内存都将在方法区中进行分配。
2.1.4 解析阶段:
虚拟机将常亮池中的符号引用替换为直接引用的过程。符号引用和内存布局无关,而直接引用的目标必定已经在内存中存在。解析动作主要针对类、字段、类方法、接口方法四类符号引用进行。
2.1.5 初始化阶段:
真正开始执行类中定义的java程序代码(字节码),是执行类构造器的过程。
2.1.6 执行机制:
Java是通过虚拟机字节码执行引擎完成字节码在虚拟机中的执行操作。不同的虚拟机实现时,执行引擎在执行Java字节码可能有解释执行(通过解释器执行)和编译执行(通过即时编译器产生编译器产生本地代码执行)两种选择,也可能两者兼备,甚至可能包含几个不同级别的编译器执行引擎。
2.2 什么是Java 的反射机制?
Java反射机制是在运行状态中,对于任意一个类都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的方法和属性;这种动态获取类的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
简单说,反射机制指的是程序在运行时能够获取自身的信息。
反射是Java中一种强大的工具,主要用于开发框架,如JavaBean、Structs、hibernate和Spring框架都大量使用反射机制,对于普通Java程序员使用比较少,只作了解。
2.2.1 Java反射机制的功能
1)可以判断运行时的对象所属的类
2)可以判断运行时对象所具有的成员变量和方法
3)通过反射机制甚至可以调用对象的private方法
4)通过反射机制可以实例化类的对象
2.2.2 实现java反射机制的类
1)class类:表示正在运行的Java应用程序中的类和借口
2)Field类:表示提供有关类或接口的属性信息,以及对它的动态访问权限
3)Constructor类:表示提供关于类的单个构造器的信息以及对它的访问权限
4)Mothed类:表示提供类或接口中某个方法信息
注意:Class类是Java 反射机制中最重要的功能类,所有获取对象的信息(方法属构造器和访问权限)都需要它来实现。
2.2.3 反射机制的优点和缺点
优点:可以实现动态实例化对象和编译,体现出很大的灵活性。
缺点:降低性能,增加复杂度。使用反射机制基本上是一种解释操作,我们可以告诉JVM希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
2.2.4 编写Java反射程序的步骤:
1)首先必须获取一个类的Class对象;
2)然后分别调用Class对象中的方法,配合使用Field类、Constructor类、Mothed类来获取一个类的属性、方法和构造器的信息。
3)使用reflection API 来操作这些信息。
2.2.5 GC回收的惩罚条件:
JVM进行GC回收的频率很高,但因为这种GC占用时间极短,所以对系统产生的影响不大,更值得关注的是GC的触发条件,因为他对系统影响很明显。总体说,有两个条件会触发GC回收:
1)档应用程序空闲时,GC会被调用
2)Java堆内存不足时,GC会被调用
由于是否进行GC回收由JVM根据系统环境决定,而系统环境在不断变化中,所以GC的运行具有不确定性,无法预计它何时必然出现。
减少GC开销的措施:
1)不要显示频繁调用System.gc().虽然只是建议而已,但很多情况下它会触发GC回收频率,降低程序的运行性能;
2)尽量减少临时对象(局部对象)的使用.临时对象或局部对象是在方法中定义,档方法执行完这些对象后将无效,不能再使用,将会被GC回收.
3)对象不用时最好显示赋值为null,这样有利于GC判断垃圾,从而提高GC的回收效率.
4)尽量使用StringBuffer,而不是String来追加字符。
5)能用基本数据类型 如int,long尽量不用对应的包装类,也尽量不要频繁装箱和拆箱。
6)尽量少用静态成员变量,这些变量属于全局变量,不会被GC回收,他们会一直占用内存知道程序退出。
7)分散对象实例化或销毁的时间,集中在短时间内实例化大量对象,会导致分配
2.3 GC
大量内存,JVM 在面临这种情况是,会频繁进行GC回收内存或整合内存碎片,从而提高GC的频率。
System.gc():调用System.gc()方法也仅仅是一个请求(或建议).JVM接受这个请求后并不是立刻做垃圾回收,而只是对几个垃圾回收算法做了加权,是垃圾h回收操作容易发生或提早发生或回收较多而已.
finalize()方法:调用该方法用于处理垃圾回收器不能处理的特俗情况.由于垃圾回收器只知道回收显示的由new实例化对象在内存堆中分配的内存空间,而无法回收采用其他方式(如本地化c/c++调用,打开的文件资源等)分配的特俗内存空间,这个时候Java允许在在类中定义一个finalize()方法来负责回收这块特俗的内存空间.
finalize()方法调用时机:一旦GC垃圾回收准备好释放对象占用的存储空间,首先回去调用finalize()方法进行一些必要的清理工作.只有到下一次再进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间.
finalize()方法的使用:该方法是Object类的方法,使用时需要重写该方法。
final、finally和finalize()的区别