一、垃圾回收
1:java 的内存分为三部分
栈:stack 局部变量。
栈内存的回收,自动回收,方法结束,就回收了。
堆:heap 对象 new 出来的对象。
动态管理分配的堆内存。进行垃圾回收。
方法区:字节码元数据,静态变量。
常驻内存数据。
2:java 垃圾回收的内存区域,指的是堆内存。
3:什么样的内存属于垃圾内存?
答:没有引用指向的对象所占用的内存就是垃圾内存。
4:如何让你对象所占用的内存成为垃圾内存?
将所有指向某个对象的引用都赋值为null。
5:如何回收垃圾内存?
jvm 中包含了垃圾回收器 garbage collection。 GC
垃圾回收器是jvm 的一个组成部分,它就负责监测回收堆内存中的垃圾内存。
垃圾回收器工作的时候会影响程序的运行,会导致程序运行速度降低。jvm 在垃圾回收的机制上,GC 运行的优先级是最低的。
规则:
1:程序处于一个闲置的状态,可能会进行一次垃圾回收。
2:当在堆中申请一块内存的时候,空间不够了,运行一次垃圾回收器。如果空间仍然不够,那么再次运行 GC 垃圾回收。如果内存还不够使用,那么就报错。堆内存溢出。
6:是否可以通过程序代码来实现运行垃圾回收器?
可以的。
在System类提供了一个方法 。System.gc();
调用System.gc():通知 jvm 运行一次垃圾回收器。但是不能保证 GC 立即执行。
public static void gc()运行垃圾回收器。
调用gc 方法暗示着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。当控制权从方法调用中返回时,虚拟机已经尽最大努力从所有丢弃的对象中回收了空间。
调用System.gc() 实际上等效于调用:
Runtime.getRuntime().gc()
7:finalize():终止方法,Object 类的默认是现实 是空实现。
如果某个对象被垃圾回收器回收,那么该对象对应的类型中的finalize()方法会被GC调用。
该方法不要主动调用,只能被动调用。
可以在finalize() 中对对象做最后的清理工作。善后的工作。
通常更建议的方式是自定义方法来进行善后的处理。
public class Test {
public static void main(String[] args) {
//final 修饰的引用数据类型的对象,对象的属性是可以被修改的。
//不能让该引用指向新的对象。
final Student STUDENT = new Student();
STUDENT.setAge(10);
// System.out.println(STUDENT.getAge());
Student student2 = new Student();
student2.setAge(101);
Student student3 = student2;
//让两个引用空指向,原来指向的对象就没有任何引用指向了。
student2.destroy();
student2 = null;
student3 = null;
//
System.gc();
}
void test(){
Student student = new Student();
}
}
class Student{
private int age;
public int getAge() {
return age;
}
void destroy(){
//关闭网络连接等等。对象善后的工作。
}
public void setAge(int age) {
this.age = age;
}
protected void finalize() throws Throwable {
System.out.println(age);
System.out.println("enclosing_type.enclosing_method()");
}
}
二、异常
java 程序中的错误,被称为异常Exception。
主要的五个关键字:try--catch--finally throw throws。
(一)try--catch
需求:让程序执行完毕。执行某些必要的代码。给用户一些错误提示。
语法:try{
//可能产生错误的代码
}catch(ArithmeticException e){
//当产生 ArithmeticException这种类型的异常的时候,在此处编写处理代码。
}
不使用try-catch时:
如果某行代码产生了异常,程序直接被终止。后续的代码都被跳过了。
深入理解:
如果在程序中出现了异常,那么该异常就交给了jvm 来处理。jvm 无法处理程序中的问题,直接终止程序运行。
使用try -catch时:
如果try 中的代码产生了异常,那么 try 代码块中的后续代码将被跳过,执行 catch 代码块中的代码,然后执行try-catch 后的代码。
如果没有产生异常:那么catch 代码块将不被执行。
深入理解:
如果产生了异常,会生成一个异常对象。如果该对象是catch 后的参数中定义的异常的类型 的实例,那么catch就可以将该异常对象捕获。
异常对象将形参变量实例化。对e 的处理,或者进行一些需要的提示信息等等。
执行完catch 代码块,执行后续的代码。
如果想让catch 可以捕获所有的异常,可以使用jdk 提供的所以的异常的公共的父类作为参数 Exception。
import java.util.Scanner;
/**
* 实现功能:输入被除数,除数,求商
*
*/
public class TestException {
public static void main(String[] args) {
//创建扫描器对象
Scanner scanner = new Scanner(System.in);
System.out.println("请您输入被除数:");
int num1 = scanner.nextInt();
System.out.println("请您输入除数:");
int num2 = scanner.nextInt();
try {//try 代码块
int result = num1 / num2;
System.out.println(num1 + "\t除以 "+num2 + "\t的结果为:"+result);
} catch (Exception e) {
//catch 代码块
//产生异常,处理的代码
System.out.println("输入了错误的数据!");
System.out.println(e);
}
System.out.println("谢谢使用!");
//在所有的键盘输入结束之后再关闭!
scanner.close();
}
}
(二)多重catch
语法:
try{
}catch(异常参数){
}catch(异常参数){
}
catch 的个数没有限制。
使用多重catch 在处理对于捕获不同的类型的异常对象,希望有不同的处理的方案。可以在不同的catch 语句中给出不同的处理方案。
try-catch中,可以没有catch,此时需要fiinally结束此语句。但catch必要和try配套使用。
import java.util.InputMismatchException;
import java.util.Scanner;
/**
* 实现功能:输入被除数,除数,求商
*
*/
public class TestException {
//记录是发布版本还是测试版本
static boolean isRelease = true;
public static void main(String[] args) {
System.out.println(test());
Scanner scanner = new Scanner(System.in);
try {//try 代码块
//创建扫描器对象
System.out.println("请您输入被除数:");
int num1 = scanner.nextInt();
System.out.println("请您输入除数:");
int num2 = scanner.nextInt();
int result = num1 / num2;
System.out.println(num1 + "\t除以 "+num2 + "\t的结果为:"+result);
//结束虚拟机的
System.exit(0);
}catch (ArithmeticException e) {
//catch 代码块
//产生异常,处理的代码
if(isRelease){
System.out.println("输入了错误的数据!除数不能为0,请您下次注意!");
}else{
//打印异常对象的栈信息
//把异常信息要暴露给程序猿,去解决问题。
e.printStackTrace();
}
}catch (InputMismatchException e){
System.out.println("输入了非法的数值型数据!");
}catch(Exception e){//最大的异常类型放到最后
//其他的异常的处理的方案。
System.out.println("都是我们的软件做的不好,我们继续努力!");
}finally {//最终代码块,不管程序出现了什么样的问题,该代码块中的代码都将被执行。
System.out.println("谢谢使用!");
//在所有的键盘输入结束之后再关闭!
scanner.close();
}
}
static int test(){
int i = 0;
try {
i ++;
//结果返回 1 先计算 返回的结果。然后再执行 finally 中的代码,最后返回计算出来的结果。
return i;
} finally {
i++;
}
}
}
(三)java 异常体系被分为了 2大类
1:运行期异常: RuntimeException 是所有的运行时异常的父类。只有在运行的时候才会出现的。
2:编译期异常 checked Exception:在编译的时候就暴露出来了。
1:运行时异常处理方式:通常不需要做特别的处理。保持代码逻辑严谨,用户体验合理即可。
2:编译期异常:
1:使用try-catch 进行捕获 并处理。 抓
2:在产生编译期异常的方法的声明处(参数列表的末尾)使用throws 将产生的编译期异常继续往外抛。抛给当前方法的调用者去处理。 抛
throw:
1:在方法的内部使用。
2:后面跟的是异常对象。
3:后面只能跟一个异常对象。
throws:
1:在方法的声明处使用,参数列表的末尾。
2:后面跟的是异常的类型。
3:后面可以跟多个异常类型,使用逗号分割。
常见异常:
1:ArithmeticException 数学异常,被0除
2:InputMismatchException 输入类型不匹配异常
3:java.lang.ArrayIndexOutOfBoundsException:数组下标越界异常。
4:java.io.IOException : javaIO 异常。
5:java.lang.NullPointerException:空指针异常,使用了尚未初始化的对象。
import java.io.File;
import java.io.IOException;
public class Test1 {
public static void main(String[] args) {
int[] array = {1,2};
System.out.println(array[2]);
//使用try-catch 进行捕获处理。
try {
test();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static void test() throws IOException{
File file = new File("c:/1.txt");
//将该编译期异常 在方法声明处 声明 该方法在被调用的时候可能会产生某种异常。
file.createNewFile();
}
}
(四)自定义异常
/**
* 自定义异常
*
*/
public class TestMyException {
public static void main(String[] args) {
Person person = new Person();
try {
person.setAge(-1);
} catch (AgeException e) {
e.printStackTrace();
}
}
}
class Person{
private int age;
public int getAge() {
return age;
}
//如果一个方法产生了一个异常对象。
public void setAge(int age) throws AgeException {
if(age < 0){
//产生一个异常对象,并抛出去
AgeException e = new AgeException(age);
throw e;
}
this.age = age;
}
}
//自定义异常
class AgeException extends Exception{
//保存非法年龄的属性
private int age;
public AgeException(int age) {
this.age = age;
}
//该异常对象的字符串表示形式
public String toString() {
return "使用了非法的年龄,数值为:"+age;
}
}
三、java常用类
(一)基本数据类型包装类
java 已经提供了八种基本数据类型。
jdk 中定义了 八种基本数据类型对应的包装类。
byte--Byte
short--Short
int--Integer
long--Long
float--Float
double--Double
char--Character
boolean--Boolean
为何要出现八种基本数据类型对应的包装类。
1:在处理很多基本数据类型的时候,需要将这些数据当作对象来对待。
2:包装类中定义了各种处理基本数据类型的方法。提供了基本数据类型到 字符串之间的相互的转换。
例:"1"+ 1中的1 这个整数要先转换为字符串(通过方法)然后在做+连接。
(二)Integer
public final class Integerextends Numberimplements Comparable
Integer 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。
此外,该类提供了多个方法,能在int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。
构造方法
Integer(int value)
构造一个新分配的Integer 对象,它表示指定的 int 值。
Integer(String s)
构造一个新分配的Integer 对象,它表示 String 参数所指示的 int 值。
int compareTo(Integer anotherInteger)
在数字上比较两个Integer 对象。
boolean equals(Object obj)
比较此对象与指定对象。
int intValue()
以int 类型返回该 Integer 的值。
static int parseInt(String s)
将字符串参数作为有符号的十进制整数进行解析。
static int parseInt(String s, int radix)
使用第二个参数指定的基数,将字符串参数解析为有符号的整数。
static String toBinaryString(int i)
以二进制(基数2)无符号整数形式返回一个整数参数的字符串表示形式。
static String toString(int i)
返回一个表示指定整数的String 对象。
static Integer valueOf(int i)
返回一个表示指定的int 值的 Integer 实例。
static Integer valueOf(String s)
返回保存指定的String 的值的 Integer 对象。
例:
import java.util.Arrays;
import com.bjsxt.util.MyUtil;
//* 定义一个Integer数组,元素个数10,然后对元素随机赋值。使用Integer.valueOf(int); 创建元素对象,
//* 然后遍历数组,打印 然后排序 ,然后再次打印。
//源代码
//静态工厂方法
public class TestInteger {
public static void main(String[] args) {
final int LEN = 10;
Integer[] integers = new Integer[LEN];
for(int i=0;i
integers[i] = Integer.valueOf(MyUtil.getRandomNumber(0, 100));
}
//打印数组内容
System.out.println(Arrays.toString(integers));
Arrays.sort(integers);
System.out.println(Arrays.toString(integers));
}
}
//很多时候需要创建一个类的不同特性的对象。
//直接通过构造方法创建不同特性的对象,需要分析构造方法的参数类型,来进行区分。
//静态工厂方法可以更好的通过方法的名字来体现创建的对象的特性。
//如果想对某个类创建的对象加以限制,可以构造方法私有化,然后通过静态工厂方法去创建你希望被外部的其他的类创建的对象。
class Student{
private int age;
private String name;
Student(int age) {
super();
this.age = age;
}
public Student() {
}
Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
//静态工厂方法。
public static Student newInstance(){
return new Student(1);
}
public static Student newDefaultStudent(){
}
}
(三)valueOf(-128~127)
1:Integer 对象一旦创建,就不能修改内部的value 值。value 值 是一个final 修饰的。
好处:安全。
坏处:需要创建大量的Integer 对象来满足 创建不同值的 Integer对象。
没有提供setValue 的方法。
只有获得value 值的方法。intValue 方法获得 Integer对象内部的value 值。
分析:通过构造方法和valueOf(int) 创建对象的区别。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
区别:使用new 调用构造方法,一定会创建一个新的对象。
使用valueOf 如果参数的值在byte 的取值范围内,则复用系统创建的对象,而不用再创建新的对象。超过范围再创建对象。
结论:优先使用valueOf 创建Integer 对象。
(四)自动装箱封箱
public class TestBoxing {
public static void main(String[] args) {
//jdk 1.5 版本提供了非常简便的语法。
//自动封箱 autoboxing 将一个基本数据类型的数据封装到一个对应的包装类的对象中。
Integer integer = 1;
//上面的代码编译之后就是下面的样子
Integer integer2 = Integer.valueOf(1);
//自动拆箱 autounboxing 将一个包装类对象直接赋值给一个对应的基本数据类型变量。
int i = integer;
//上面的代码编译之后就是下面的样子
int value = integer.intValue();
}
}
(五)System系统类
public final class Systemextends ObjectSystem 类包含一些有用的类字段和方法。它不能被实例化。
在System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
in : 对应着标准输入设备 ,键盘
out:标准输出设备 ,控制台。
常用方法:
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
static long currentTimeMillis()
当前时间与协调世界时1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。
static void exit(int status)
终止当前正在运行的Java 虚拟机。
static void gc()
运行垃圾回收器。
static long nanoTime()
返回最准确的可用系统计时器的当前值,以毫微秒为单位。
static void runFinalization()
运行处于挂起终止状态的所有对象的终止方法。
static void setIn(InputStream in)
重新分配“标准”输入流。
static void setOut(PrintStream out)
重新分配“标准”输出流。
(六)Math类
public final class Mathextends Object
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
static double E :比任何其他值都更接近e(即自然对数的底数)的 double 值。
static double PI :比任何其他值都更接近pi(即圆的周长与直径之比)的 double 值。
static int abs(int a)
返回int 值的绝对值。
static double cbrt(double a)
返回double 值的立方根。
static double ceil(double a) 向上取整
返回最小的(最接近负无穷大)double 值,该值大于等于参数,并等于某个整数。
static double floor(double a) 向下取整
返回最大的(最接近正无穷大)double 值,该值小于等于参数,并等于某个整数。
static double max(double a, double b)
返回两个double 值中较大的一个。
static double min(double a, double b)
返回两个double 值中较小的一个。
static double pow(double a, double b)
返回第一个参数的第二个参数次幂的值。
static double random()
返回带正号的double 值,该值大于等于 0.0 且小于 1.0。
static long round(double a)四舍五入
返回最接近参数的long。
static double sqrt(double a)
返回正确舍入的double 值的正平方根。
static double toDegrees(double angrad)
将用弧度表示的角转换为近似相等的用角度表示的角。
static double toRadians(double angdeg)
将用角度表示的角转换为近似相等的用弧度表示的角。