JavaSE复习day5
胡家伟
16.equals&toString&编写编译运行
equals
概念
equals是在object类中的方法,在object中equals是用来检查两个参数是否引用的是同一个对象
obj.equals(obj2) 若是返回true说明两者引用同一个对象
源码
public boolean equals(Object obj) {
return (this == obj);
}
我们实际开发中经常比较的是两个对象的内容是否相等,因此就要重写equals,注意只能在一个类里比
//人类
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(){
}
@Override
public boolean equals(Object obj) {
//判断地址是否相同
//判断测试的是否是同一个对象
//如果是同一个对象,毋庸置疑,它应该返回True
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(obj instanceof Person){
//向下转型
Person person = (Person) obj;
if(this.name.equals(person.name) && this.age==person.age){
return true;
}
}
return false;
}
}
//测试类
public class Test {
public static void main(String[] args) {
Person p1 = new Person("胡家伟",22);
Person p2 = new Person("胡家伟",22);
if(p1.equals(p2)){
System.out.println("p1与p2相等");
}
}
}
输出
p1与p2相等
equals与==的区别
“==”用来比较基本数据类型时直接比较数值,比较引用数据类型(class,接口...)时比较对象的引用和地址
equal没有重写之前比较的也是对象的地址,但是重写之后比较的两个对象的内容是不是相同
toString
重写toString方法来输出自己想要的内容。
重写前
//toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//主方法
Person p1 = new Person("胡家伟",22);
System.out.println(p1);
输出
Person{name='胡家伟', age=22}
重写后
//toString方法
@Override
public String toString() {
return "我叫" + this.name + ",今年" + this.age + "岁了。";
}
//主方法
Person p1 = new Person("胡家伟",22);
System.out.println(p1);
输出
我叫胡家伟,今年22岁了。
编写编译运行
JVM、JRE、JDK
- JVM:Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。
- JRE:JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。但是,它不能用于创建新程序。
- JDK:JDK 是 Java Development Kit 缩写,它是功能齐全的 Java SDK。它拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序。
cmd如何运行java文件
-
通过cd命令到达要执行.java文件的根目录
cd xxxx
-
使用javac命令编译.java文件,变成字节码.class文件
javac xxx.java
-
使用java命令执行.class文件
java xxx.class
字节码
在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class
的文件),它不面向任何特定的处理器,只面向虚拟机。
字节码的优点
Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以, Java 程序运行时相对来说还是高效的(不过,和 C++,Rust,Go 等语言还是有一定差距的),而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。
Java 程序从源代码到运行的过程
.java --> javac编译 --> .class --> 解释器&JIT --> 机器码 -->计算机运行
为什么说 Java 语言“编译与解释并存”?
这是因为 Java 语言既具有编译型语言的特征,也具有解释型语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class
文件),这种字节码必须由 Java 解释器来解释执行。
17.异常处理
异常概念
-
一个程序在执行的过程中,遭遇了非正常的状况,叫做异常。
- 逻辑疏忽不能叫异常。
- 编译检查出来的错误也不叫异常。
-
当一个异常发生的时候:
-
程序终止运行。
-
展示报错信息。
-
-
程序会以非正常终止。
异常处理概念
- 异常处理就是在代码中所定义的一种代码,这种代码将会在异常发生的时候执行。
- 并且保证程序即使发生了异常,也能继续正常的执行直到结束。
异常与错误(Exception与Error)
将异常按照严重性我们可以分为Exception和Error。
在异常处理API中,Exception和Error为异常类型的两大分支。
|——Throwable(实现类描述java的错误和异常)
|——Error(错误)
|——Exception (异常)
Exception
- Exception字面翻译为“意外”。
- 其他因编程错误或偶然以外因素导致的一般问题。
- 针对于异常通常通过异常处理方式进行处理。
空指针 | 数组下标越界 |
---|---|
演示代码 | 演示代码 |
public static void main(String[] args) { Object o = null; System.out.println(o.toString()); } |
public static void main(String[] args) { int[] arr = new int[10]; System.out.println(arr[11]); } |
执行结果 | 执行结果 |
Exception in thread "main" java.lang.NullPointerException at com.exception.Test.main(Test.java:7) |
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at com.exception.Test.main(Test.java:7) |
Error
- Error字面翻译为“错误”。
- Error是指JVM无法处理的严重性问题,相对于Exception的严重性要高。
- 使用后面即将学习的异常处理方式对于Error的处理也同样有效但没有意义,因为Error本身最终需要通过将程序修改正确解决。
栈溢出 | 堆溢出 |
---|---|
演示代码 | 演示代码 |
public static void main(String[] args){ int[] arr = new int[1024 * 1024 * 1024]; } |
public static void main(String[] args){ main(args); } |
执行结果 | 执行结果 |
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at com.exception.Test.main(Test.java:5) |
Exception in thread "main" java.lang.StackOverflowError at com.exception.Test.main(Test.java:5) |
区分
通过异常类型的类名区分是区分一个异常属于Exception,Error的关键,通常异常类型结尾为Exception的为 Exception,同样结尾为Error的则为Error。
编译期异常与运行期异常
概述
-
将异常按照发生时期划分可以分为“编译期异常”和“运行期异常”。
-
多个名词代表同一件事物
-
编译期异常也被称之为“编译时异常”、“受检异常”。
-
运行期异常也被称之为“运行时异常”、“非受检异常”。
-
-
编译期异常所指必须在编译的时期就必须进行有效处理的异常,运行期异常所指可以不在编译期必须处理的异常。
理解
Java程序从开发到运行需要经历
- 编写源代码
- 执行javac将源代码编译为字节码
- 执行java将字节码加载到JVM中运行
“编译期异常”实际上是在编译期进行检查异常是否已经进行了有效的处理,如果没有进行有效的处理则无法通过编译。
- 编译这个行为首先我们本身无法干预。
- 而编译之前源代码是咱们自己手写的。
- 综上,“编译期异常”必须在源代码中定义好异常处理代码。
“运行期异常”实际上是在运行期检查异常是否发生并且是否进行了处理。
- 编译行为和运行行为我们都无法进行控制。
- 而运行期异常即使不处理也可以正常通过编译。
- 综上,“运行期异常”可以编写异常处理代码也可以不编写。
|——Throwable(实现类描述java的错误和异常)
|——Error(错误)
|——Exception (异常)
|——RuntimeException(运行期异常)
继承自Exception的类型称之为“编译期异常”, 继承自RuntimeException的类型为“运行期异常”。
为什么存在运行期异常
- 发生概率高的异常通常被定义为“编译期异常”,发生概率相对低的异常被定义为“运行期异常”。
- 不存在运行期异常,那么在日常开发过程中我们需要频繁编写异常处理代码,会非常耗时费力
解读报错
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11
at com.exception.Test.main(Test.java:7)
所发生的线程
Exception in thread "main"
异常类型
java.lang.ArrayIndexOutOfBoundsException
提示信息
11
发生位置(可能为多行,例如main方法调用了a方法,a方法调用的b方法,如果b方法执行出错,那么相对a和main方法也执行出错)
at com.exception.Test.main(Test.java:7)
异常捕获
抓抛模型
- 抛:程序在正常执行的过程中一旦出现异常就会在异常代码处生成一个对应异常类的对象,就会将此异常抛出。一旦 抛出对象之后,之后的代码将不会再执行。
- 抓:异常处理的方式
- 方式1:try-catch-finally
- 方式2:throws
try-catch-finaly
关键字 | try | catch | finally |
---|---|---|---|
用途 | 进行异常的识别 | 进行对于不同的异常执行处理 | 对于代码执行进行善后 |
语法 | 在整个语法中只存在一个 编写可能出现异常的代码 |
在整个语法中可以存在多个 定义异常类型和处理异常方法代码 |
一定会执行的代码 |
try {
Object o = null;
System.out.println(o.toString());
} catch (NullPointerException e) {//catch可以有多个
System.out.println("发生了空指针错误");
} finally {
System.out.println("异常处理结束");
}
try
- 通常将可能发生异常的代码放在try语句块中。
- try代码块中一旦发生异常,那么将会生成一个对应异常类型的对象,根据此对象的类型去catch语句块中匹配。
catch
- catch与finally互为可选的,但是try是必须的。
- catch块小括号中定义了某种异常类型,那么意味着这个catch块可以捕获此类型以及属于此类型子类类型的异常。
- 对于要捕获多种异常可以定义多个catch以声明不同的捕获异常类型,在定义多个catch语句块的时候注意,如果多个catch语 句块中要捕获的异常有继承关系,那么子类异常类型要写在父类异常上方,否则无法通过编译。
- 常用的异常信息展示方法
- String getMessage():获取异常描述信息
- printStackTrace():打印异常堆栈信息
finally
- catch与finally互为可选的,但是try是必须的。
- 无论是否发生了异常都必须要执行的代码编写在finally语句块中。
- finally语句块存在的意义
- finally具有强硬的特性。
- 会抢在return之前执行
- 会抢在break之前执行
- 会抢在continue之前执行
- 硬不过System.exit();
- 如果catch语句块中也遭遇了异常,那么finally一定还是会执行。
- finally具有强硬的特性。
- 使用finally的主流场景
- 释放资源
- 对于某些资源,垃圾回收机制本身对其是无法完成回收的
- 对于这一类资源需要开发人员手动明确编写释放代码对其进行释放
- 为了保障释放资源的代码无论是否发生异常都一定会执行,通常这种释放资源的代码需要放在finally中。
- 这些资源包含但不限于: 数据库连接、IO流、网络连接
- 释放资源
throws
定义一个功能,进行除法运算例如(div(int x,int y))如果除数为0,进行处理。
功能内部不想处理,或者处理不了。就抛出使用throw new Exception(“除数不能为0”); 进行抛出。抛出后需要在函数上进行声明,告知调用函数者,我有异常,你需要处理如果函数上不进行throws 声明,编译会报错。例如:未报告的异常 java.lang.Exception;必须对其进行捕捉或声明以便抛出throw new Exception(“除数不能为0”);
public static void div(int x, int y) throws Exception { // 声明异常,通知方法调用者。
if (y == 0) {
throw new Exception("除数为0"); // throw关键字后面接受的是具体的异常的对象
}
System.out.println(x / y);
System.out.println("除法运算");
}
main方法中调用除法功能,调用到了一个可能会出现异常的函数,需要进行处理。如果调用者没有处理会编译失败。
两种处理方式:
1.try-catch
public static void main(String[] args) {
try {
div(2, 0);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("over");
}
public static void div(int x, int y) throws Exception { // 声明异常,通知方法调用者。
if (y == 0) {
throw new Exception("除数为0"); // throw关键字后面接受的是具体的异常的对象
}
System.out.println(x / y);
System.out.println("除法运算");
}
2.继续抛出throws
public static void main(String[] args) throws Exception {
div(2, 0);
System.out.println("over");
}
public static void div(int x, int y) throws Exception { // 声明异常,通知方法调用者。
if (y == 0) {
throw new Exception("除数为0"); // throw关键字后面接受的是具体的异常的对象
}
System.out.println(x / y);
System.out.println("除法运算");
}
throw和throws的区别
相同:都是用于做异常的抛出处理的。
不同点:
- 使用的位置: throws 使用在函数上,throw使用在函数内
- 后面接受的内容的个数不同:
- throws 后跟的是异常类,可以跟多个,用逗号隔开。
- throw 后跟异常对象。
自定义异常
//自定义非法年龄异常
public class IllegalAgeException extends RuntimeException{
public IllegalAgeException(String message){
super(message);
}
}
//人类
public class Person {
private int age;
private String name;
public Person(){
}
public void setAge(int age) {
if(age < 0 || age > 150){
throw new IllegalAgeException("传入的年龄" + age + "不合理");
}
this.age = age;
}
}
//测试类
public class Test {
public static void main(String[] args) throws Exception {
try {
Person person = new Person();
person.setAge(1000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
输出
传入的年龄1000不合理
标签:Exception,java,复习,day5,编译,JavaSE,main,异常,public
From: https://www.cnblogs.com/chiawei/p/16969804.html