Object类
是所有对象的直接或者间接父类
该类中定义的是所有对象都具备的功能
equals(object obj)
public boolean equals(Object obj) {
return (this == obj);
}
方法用于比较两个对象,如果这两个对象引用指向的是同一个对象,那么返回 true,否则返回 false。
一般 equals 和 == 是不一样的,但是在 Object 中两者是一样的
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1.equals(s2));
}
}
class Student {}
子类一般都要重写这个方法。
class Student {
private int num;
Student(){};
Student(int num){
this.num = num;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
return false;
Student s = (Student)obj;
return this.num == s.num;
}
}
hashCode
public native int hashCode();
方法主要用于获取对象的散列值。Object 中该方法默认返回的是对象的堆内存地址
public class Main {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.hashCode());//189568618
System.out.println(Integer.toHexString(s.hashCode()));//b4c966a
}
}
class Student {}
toString
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
返回一个 String 对象,一般子类都有覆盖。
默认返回格式如下:对象的 class 名称 + @ + hashCode 的十六进制字符串。
public class Main {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.toString());//demo.Student@b4c966a
}
}
class Student {}
内部类
访问规则:
- 内部类可以直接访问外部类中的成员,包括私有
- 要访问内部类,必须建立内部类对象
内部类可以设置私有(private),外部类不可以设置私有(private)
class Student {
private int x,y;
Student(int x,int y)
{
this.x = x;
this.y = y;
}
class Rant{
public void num(){
System.out.println(x*y);
}
}
}
其他类访问内部类的成员
外部类.内部类 参数名 = 外部类对象.内部类对象;
Student.Rant r = new Student(5,5).new Rant();
当内部类中的变量名 与 外部类的变量名冲突,
内部类中的this,指向本内部类,访问外部类需要使用外部类名.this 标识参数
class Rant{
public void num(){
int x = 1,y = 1 ;
System.out.println(Student.this.x*y);// 5
}
}
静态内部类
具备static特性
当内部类被static修饰后,只能直接访问外部类中的static成员,存在访问局限
直接访问静态内部类
public class Main {
public static void main(String[] args) {
new Student.function().demo1();
Student.function.demo2();
}
}
class Student {
static class function{
public void demo1(){
System.out.println("Demo One !!!");
}
public static void demo2(){
System.out.println("Demo Two!!!");
}
}
}
访问内部类的非静态方法
new Student.function().demo1();
访问内部类的静态方法
Student.function.num();
当内部类中定义了静态成员,该内部类必须是static
当外部类中的静态方法访问内部类,该内部类必须是static
内部类定义在局部时:
- 不可以被成员修饰符修饰
- 可以直接访问外部类中的成员,但不可以访问局部中的变量,只能访问被final修饰的局部变量
匿名内部类
匿名内部类 —— 内部类的简写格式
匿名内部类必须要继承一个类或者实现一个接口
new 父名 或 接口(){
定义子类内容
};
匿名内部类就是一个匿名子类对象,可以理解为带内容的对象
匿名函数每次在智能调用一个内部方法
new People(){
public void speak(){
System.out.println("Hello!!!");
}
public void sleep(){
System.out.println("World!!!");
}
}.sleep();
通过命名参数,来访问匿名内部类中的方法
// 一个接口
interface People{
public abstract void speak();
}
class Student {
public void function(){
// 创建匿名内部类
People p = new People(){
public void speak(){
System.out.println("Hello!!!");
}
public void sleep(){
System.out.println("World!!!");
}
};
p.speak();
//p.sleep();// 错误 ,因为接口中不存在无法,调用子类方法
}
}
通常情况下,匿名内部类中的方法最好不要不超过三个
使用Object类创建匿名内部类时,不能创建对象去引用内部方法,因为 Object 内部不在存在相关方法
new Object()
{
public void num(){};
}.num();
异常
处理异常的思想
不同的异常交给把不同的的对象进行处理
例如:数据库的使用
public static void main(String[] args) throws 自定义异常{
try {
// 连接数据库
// 存储数据
}
catch (SQLExpectiom e)
{
// 数据库管理员处理异常
throw new 自定义异常();//返回一些信息,告诉Java程序员原因
}
finally {
// 关闭数据库
};
}
程序在运行是出现不正常情况
对于问题的划分,两种
- 严重的(错误,不可处理),java通过Error类进行描述
- 非严重的(异常,可以使用针对想的处理方式进行处理),java通过Exceptions类进行描述
无论是Error还是Exceptions都具有共性内容
Trowable类 是 java中所有错误或者异常的超类(父类)
try catch
try {
// 要检测的代码
}
catch (异常类 变量)
{
//处理异常的代码
}
finally {
//一定会执行的语句
};
对捕获的异常进行常见的方法操作
String getMessage() —— 获取异常信息
String toString() —— 异常名称以及异常信息
String printStackTrace() —— 异常名称,异常信息,异常出现的位置
jvm默认的异常处理,就是调用printStackTrace()方法,打印异常的堆栈的跟踪信息
throws
在功能上通过throws的关键字声明该功能可能会出现的问题
public void num() throws Exception{} ;
多异常处理
- 声明异常时,建议声明更为具体的异常,因此处理的可以更加具体
- 若声明几个异常,就对象有几个catch块,不要定义多余的catch块
- 若多个catch块中的异常出现继承成功关系,父类异常catch块放在最下面
在建立进行catch处理时,catch中一定要定义具体处理方式,不能简单的定义抛出异常原因,也不要简单的抛出一条输出语句
一般情况下,会将异常信息保存为日志形式,以便查阅
自定义异常
项目中会出现一些特有的问题
而这些问题并未被java所描述并封装对象
对于这些问题可以按照java的对问题封装的思想,将特有问题,进行自定义异常封装
自定义异常 必须继承 Exception
,原因:
可抛性是Trowable这个体系独有的的特点
只有这个体系中的类和对象才可以被throws 和 throw操作
- 通过继承,创建方法
- 父类中已经把异常信息的操作完成
- 子类只要在构造时,将异常信息传递给父类通过super语句,就可以直接通过getMessage() 获取
class FuShuException extends Exception {
// 处理异常信息
FuShuException(String msg){
super(msg);
}
}
- 自定义方法无法自动引入,需要手动通过throw关键字抛出一个自定义异常对象
- 当函数内部出现throw抛出异常对象,就必须给出对应的处理动作
- 在内部trycatch处理
- 在函数上声明让调用者处理
- 一般情况下,函数内出现异常,函数需要声明
class Demo
{
int num(int a,int b) throws FuShuException
{
if(b<0||a<0)
throw new FuShuException("The number is negative.");
return a+b;
}
}
- 使用自定义异常
- try catch 捕获异常
- throws 抛出异常
public class Main {
public static void main(String[] args) {
try {
new Demo().num(-5,6);
}catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
throw 与 throws
throw —— 使用在函数上
throws —— 使用在函数内
throws —— 后跟异常类,可以是多个,用逗号隔开
throw —— 后跟异常对象
RuntimeException
Exception 中一个特殊的子类异常,RuntimeException
//正常异常的情况,需要多次抛出
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(new Demo().num(-5,0));
System.out.println("Over");
}
}
class Demo
{
int num(int a,int b) throws Exception
{
if (b==0)
throw new Exception("除数为零!");
return a/b;
}
}
若在函数内抛出 RuntimeException异常或其子类,函数不用声明,编译可以通过
public class Main {
public static void main(String[] args) {
System.out.println(new Demo().num(-5,0));
System.out.println("Over");
}
}
class Demo
{
int num(int a,int b)
{
if (b==0)
//throw new Exception("除数为 零 !");//直接报错,代码存在问题
throw new RuntimeException("除数为零!");//不会报错,会抛出异常信息
return a/b;
}
}
若在函数上声明 RuntimeException异常或其子类,调用者可以不用进行处理,编译可以通过
public class Main {
public static void main(String[] args){
System.out.println(new Demo().num(-5,0));
System.out.println("Over");
}
}
class Demo
{
int num(int a,int b) throws RuntimeException
{
return a/b;
}
}
不需要声明,因为不需要让调用者处理,当该异常发生,希望程序停止,因此在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正
自定义异常时,若该异常的运算无法继续运算,就让该自定义异常继承RuntimeException
class FuShuException extends RuntimeException {
// 处理异常信息
FuShuException(String msg){
super(msg);
}
}
class Demo
{
int num(int a,int b)
{
if(b<0||a<0)
throw new FuShuException("The number is negative.");
return a+b;
}
}
异常分类(两种):
- 编译时被检测的异常
需要在方法后面标识,调用者也需要抛出异常
int num(int a,int b) throws Exception
{
if(b<0||a<0)
throw new Exception("The number is negative.");
return a+b;
}
- 编译时不被检测的异常(运行时异常,RuntimeException 以及 其子类)
异常 finally
finally 中存放一些一定会被执行的代码
finally 代码块 ,通常 用于 关闭资源
处理语句的格式
格式一:
try{}
catch (){}
格式二:
try{}
catch (){}
finally {}
格式三:
try{}
finally {}
覆盖异常
- 子类在覆盖父类时,若父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类
class AException extends Exception {
// 处理异常信息
}
class BException extends AException {
// 处理异常信息
}
class CException extends Exception {
// 处理异常信息
}
class People
{
void show() throws AException{}
}
class Student extends People {
void show() throws BException {}
// 可以使用 AException BException异常,必须继承父类的异常处理
//不能使用 CException异常,以及其他异常,也就是父类不包括的异常
}
- 若父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集
- 若父类或者接口的方法中没有抛出异常,那么子类在覆盖方法时,也不可以抛出异常
- 若子类方法发生异常,就必须进行 try处理,绝对不抛出
练习
求长方形面积,不能出现非法数值
public class Main {
public static void main(String[] args){
new Rect(-5,6).getArea();
}
}
// 求面积的接口
interface Shape
{
void getArea();
}
// 出现非法值的自定义异常
class NoValueException extends RuntimeException
{
NoValueException(String msg){
// 继承父类的异常描述
super(msg);
}
}
// 求长方形的面积
class Rect implements Shape
{
// 设置长,宽
private int let,wid;
// 初始化,防止数据异常,引入自定义异常,不需要标记,因为继承自RuntimeException
Rect(int let,int wid) {
if (let <= 0 || wid <= 0)
throw new NoValueException("出现非法值");
this.let = let;
this.wid = wid;
}
public void getArea(){
System.out.println(let*wid);
}
}
总结异常
将问题进行对象的封装
异常体系
Throwable
|--Error
|--Exception
|--RuntimeException
异常体系的特点:
- 异常体系中所有类以及建立的对象都具备可抛行性
- 可以被throw和throws所操作
当函数内容由throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败
注意:RuntimeException除外
若函数声明了异常,调用者需要进行处理,处理方式可以 throws 可以 try
异常分类:
- 编译时被检测异常
- 该异常编译时,若没有处理,编译失败
- 该异常被标识,代表可以处理
- 运行时异常(编译阶段不检查)
- 在编译时,不需要处理,编译器不检查
- 该异常发生,建议不处理,让程序停止,修改代码
finally 一定会执行的内容,通常用于释放资源 ,只有一种情况不会执行,当执行 System.exit(0);
异常的好处:
- 将问题进行封装
- 将正常流程代码和问题处理代码分离,方便阅读
异常的处理原则:
- 处理方式两种,try 或 throws
- 调用到抛出异常的功能时,抛出几个就处理几个,一个try对应多个catch
- 多个catch,父类的catch放到最下边
- catch内,需要定义针对想的处理方式,不能简单地定义 e.printStackTrace(); 或 输出语句,也并不要不写
- 当捕获到的异常,本功能无法处理,可以继续在catch中抛出
try {
throw new AException();
}catch (AException e)
{
throw e;
}
- 若异常处理不了,但并不属于该功能出现的异常,可以传唤后,再抛出和该功能相关的异常
包
- 对类文件进行分类管理
- 给类提供多层命名空间
- 写在程序文件的第一行
- 类名的全程是 : 包名.类名
- 包是一种封装形式
使用javac 编译 java 文件
当存在包package时,使用如下格式:
javac -d 包的位置 java文件
java 包名.类名
包与包之间的访问
包与包之间进行访问,被访问的包中的类以及类中的成员需要被public总结
使用其他包的内容格式
包名.方法名
不同包之间的类也可以相互继承
protected
保护
不同包的子类可以直接访问父类中被 protected 权限修饰的成员
包与包之间可以使用的权限只有两种
- public
- protected
修饰符权限
权限问题(权限由上到下依次减小)
- public
- protected
- default(默认,什么都不写)
- private
- |public|protected|default|private
---|---|---|---|---
同一个包中| Yes | Yes | Yes | Yes
同一个包中| Yes | Yes | Yes | No
子类 | Yes | Yes | No | No
不同包| Yes | No | No | No
导入import
为了简化类名书写,使用关键字 import
import 导入的是包中的类
import 包名.*;
例如: import Hello.*;
包中若存在子包,也需要引入
格式:
import 父包 . 子包 .*;
一般不建议引入包的全部内容,而是按照需要引入特定的类,而不是使用通配符 *
注意保证包的唯一性,需要用特定的命名方式
jar包
java压缩包
- 方便项目携带
- 方便与使用,只要在classpath设置jar的路径即可
- 数据库驱动,SSH框架等都是jar包的体现
通过JDK中的jar.exe,来打包jar文件
打开cmd,索引到保存在的目录下,使用jar.exe 将 需要打包的文件生成为一个jar文件
使用命令 jar --help,或如下内容查看如何使用jar.exe
-?, -h, --help 查看详细的jar使用说明
--help-extra 提供额外选项的帮助,查看详细的jar使用说明
jar --version 查询jar.exe的版本
-c, --create 创建jar文件
-i, --generate-index=FILE 为指定的 jar 档案生成索引信息
-t, --list 查看jar包中的类
-u, --update 更新现有 jar 档案
-x, --extract 从档案中提取指定的 (或全部) 文件
-d, --describe-module 输出模块描述符或自动模块名称
在任意模式下有效的操作修饰符:
-C DIR 更改为指定的目录并包含,DIR问文件目录
-f, --file 档案文件名。
-v, --verbose 查看jar包具体的生成过程
使用这些命令需要配合 -f(指定jar包) 使用
例如:
jar -cf MyJar.jar demo Hello
命名jar包 —— MyJar.jar
引入的package —— demo,Hello
网友评论