1 内部类

内部类的作用:

  • 内部类提供了更好的封装,可以把内部类隐藏于外部类之内,不允许同一个包中的其他类访问该类。(例如给“牛”这个类组合一个“牛腿”,则可以把牛腿定义成内部类,因为牛腿脱离了牛没有意义)
  • 内部类成员可以直接访问外部类私有数据,因为内部类被当成其外部类成员。
  • 匿名内部类适合用于创建仅需要使用一次的类。

内部类除了必须定义在其他类里面之外,还有如下区别:

  • 内部类可以比外部类多使用三个修饰符:private 、protected 、static (被当作成员)
  • 非静态内部类不能拥有静态成员。

成员内部类(方法外,外部类里面定义的)的 class 文件的格式是 OuterClass$InnerClass.class。

1.1 非静态内部类

当调用非静态内部类的实例方法时,必须有一个非静态内部类实例,而非静态内部类实例必须寄生在外部类实例里。

  • 非静态内部类方法访问某个变量时:优先在方法内寻找局部变量;接着在内部类找;接着在外部类找;如果依然不存在,则编译错误,提示找不到改变量。如果外部类成员变量、内部类成员变量、局部变量同名,则可以用 外部类名.this.val、this.val、val 来区分。
  • 如果外部类需要访问非静态内部类的成员,则必须显示创建非静态内部类对象来调用访问其实例成员。
  • 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例等。
  • 非静态内部类里不能有静态方法、静态成员变量、静态代码块。(可以有普通初始化块)

1.1.1 创建非静态内部类实例

  • 在外部类中,可以直接按照普通的创建对象的形式创建内部类实例
  • 在其它类中,需要先创建外部类实例,再通过外部类实例创建内部类实例,内部类实例寄生于外部类实例。
 OuterClass outer = new OuterClass();
(OuterClass.)InnerClass inner = outer.new Inner();

(OuterClass.)InnerClass inner = new OuterClass().new Inner();

1.2 静态内部类

使用 static 来修饰一个内部类,则这个内部类就属于外部类本身。静态内部类可以包含静态成员,也可以包含非静态成员,但是静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。

静态内部类是外部类的一个静态成员,因此外部类的所有方法、所有初始化块中可以使用静态内部类来定义变量、创建对象。

外部类依然不能直接访问静态内部类的成员,但可以通过类名(或对象)作为调用者访问静态内部类的成员。

PS Java 还允许在接口里定义内部类,接口里的内部类默认是 public static 修饰

1.2.1 创建静态内部类实例

  • 在外部类中,可以直接按照普通的创建对象的形式创建内部类实例
  • 其他类中:
 (OuterClass.)InerClass iner = new (OuterClass.)InnerClass();

1.3 局部内部类

声明周期和所在方法相同,生成 class 文件 格式为:OuterClass$NInnerClass.class。对比成员内部类,多了一个数字(N),因为同一个类了里可能有两个以上同名的局部内部类。

局部内部类若访问了局部变量(方法中定义的),则会自动给改变量加上 final 修饰符,意味着不能修改局部变量的值。

1.4 匿名内部类

适合创建只需要使用一次的类,定义格式如下:

 new 实现接口()|父类构造器(实参列表){
//类体
}

匿名内部类必须继承一个父类,或实现一个接口,且最多继承一个父类或实现一个接口。

规则:

  • 匿名内部类不能是抽象类
  • 不能定义构造器,但可以定义初始化块,来完成构造器的工作。

当通过实现接口创建匿名内部类时,括号里不能有参数;

当通过继承父类来创建匿名内部类时,将拥有和父类相似的父类构造器(相同的形参列表),会根据参数列表调用父类构造器。类体里可以重写父类的普通方法。

同样的匿名内部类访问局部变量时,会自动添加 final 修饰。

2 异常处理

2.1 异常

异常是指在程序的运行过程中所发生的不正常的情况,它会中断正在运行的程序。java中通过异常处理机制为程序提供异常处理的能力,保持程序继续运行而不中断!

涉及异常处理的常用关键字有:try、catch、finally、throws、throw

2.2 try - catch

把有可能产生异常的代码放到try代码块中,catch代码块负责捕获并处理异常。

Exception是所有异常类的直接或者间接父类。往下又分为 RuntimeException 和 检查时异常。检查时异常要求编译时必须对其进行异常处理,而 RuntimeException 没有要求。

运行时异常:包括RuntimeException及其所有子类。不要求程序必须对它们作出处理,比如InputMismatchException、ArithmeticException、NullPointerException等。即使没有使用try-catch或throws进行处理,仍旧可以进行编译和运行。如果运行时发生异常,会输出异常的堆栈信息并中止程序执行。

Checked异常(非运行时异常):除了运行时异常外的其他异常类都是Checked异常。程序必须捕获或者声明抛出这种异常,否则出现编译错误,无法通过编译。处理方式包括两种:通过try-catch捕获异常,通过throws声明抛出异常从而交给上一级调用方法处理

常见的运行时异常

ArithmeticException:数学计算异常。比如除数为0
InputMismatchException:输入不匹配异常
ArrayIndexOutofBoundsException:数组下标越界异常。
NullPointException:空指针异常,对象没有初始化就使用时,jvm会抛出该异常
IllegalArgumentException:非法参数异常。
ClassCastException:强制类型转换异常。
NumberFormatException:数字格式化异常。比如把“abc”格式化成数字。

常见的检查时异常:

ClassNotFoundException:类没有被发现异常。
SQLException:数据库相关异常
IOException:IO操作异常
ParseException:解析错误异常
FileNotFoundException:文件未发现异常。

当 catch 后面的参数和发生的异常类型不匹配时,捕获异常失败,程序会终止,并由系统抛出异常提示。

可以采用多重 catch ,分别对不同类型的异常进行处理,类似于 if - else if。

2.3 try - catch - finally

把有可能产生异常的代码放到try中,catch负责匹配并处理异常,finally块用于进行收尾工作(关闭数据库、关闭文件、释放内存等资源),不管是否发生异常,finally内的代码都将执行。只有一种情况下不执行 finally 内的代码:在 try 或 catch 内部用 System.exit(0); 退出 JVM,finally 将没机会执行。

可以省略掉 catch,捕获到异常之后不对异常进行任何处理,直接进入 finally。

若有 return 关键字在 try - catch - fianlly 内部,系统的执行顺序总是执行到 return 的前一句, 接着执行完 finally 内部代码后再 return,不管 return 是存在于 try 还是 catch。

2.4 声明异常

2.4.1 throws 关键字

当一个方法可能存在异常,而此时自身又无法更好的处理,可以交给外界处理。此时用throws声明并抛出异常。开发者可以根据需要声明检查时异常(Exception或者非运行时异常)和运行时异常(RuntimeException或其子类)。如果调用处也不知道如何处理异常,可选择继续声明异常,我们把这个过程称为异常上抛,继续 throws。

2.4.2 声明异常与方法重载、重写

方法的重载完全不会受到声明异常的影响,若类中某一方法声明了异常,其重载的方法声不声明异常都可以。

但是重写不一样,以下四种情况都是合法的:

  1. 父类方法声明了异常(检测时或运行时),子类可以不声明任何异常。
  2. 父类方法声明没有声明任何异常(检测时或运行时),子类不声明异常或者声明运行时异常。(不能声明检测时异常)
  3. 父类声明了异常(检测时或运行时),子类声明完全一样的异常。
  4. 父类声明了检测时异常,子类声明了运行时异常。

2.5 手动抛出异常

除了系统自动抛出异常外,有些问题需要开发者手动抛出异常。使用关键字 throw

  public void setGender(String gender) throws Exception{
if(gender.equals("男") || gender.equals("女")) {
this.gender = gender;
}else {
throw new Exception("性别不合法!");
}
}

2.6 自定义异常

如果开发者需要手动抛出的异常在系统不存在,可以自定义异常。如果要自定义异常,首先要确定异常类型,如果异常是运行时异常,必须继承 RuntimeException 或其子类;如果异常是检查时异常,必须继承 Exception 或其子类。异常的命名方式,参考系统命名方式,以Exception结尾。

 public class AgeException extends Exception{

     public AgeException() {
super();
} public AgeException(String message) {
super(message);
}
}

3 LeetCode

58. 最后一个单词的长度

给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。如果不存在最后一个单词,请返回 0 。

说明:一个单词是指由字母组成,但不包含任何空格的字符串。

示例:

输入: "Hello World"
输出: 5

源码:

 class Solution {
public int lengthOfLastWord(String s) {
int num = 0;
for(int i = s.length() - 1; i >= 0; i--){
if (s.charAt(i) == ' ' && num == 0)
continue;
if (s.charAt(i) != ' ')
num++;
else
break;
}
return num;
}
}

内部类、异常以及 LeetCode 每日一题的更多相关文章

  1. 【js】Leetcode每日一题-制作m束花所需的最少天数

    [js]Leetcode每日一题-制作m束花所需的最少天数 [题目描述] 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k ...

  2. 【JavaScript】Leetcode每日一题-在D天内送包裹的能力

    [JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...

  3. 【js】Leetcode每日一题-完成所有工作的最短时间

    [js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...

  4. 【js】Leetcode每日一题-数组异或操作

    [js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...

  5. 【js】Leetcode每日一题-解码异或后数组

    [js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...

  6. 【JavaScript】Leetcode每日一题-青蛙过河

    [JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...

  7. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  8. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

  9. 【JavaScript】Leetcode每日一题-递增顺序搜索树

    [JavaScript]Leetcode每日一题-递增顺序搜索树 [题目描述] 给你一棵二叉搜索树,请你 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没 ...

随机推荐

  1. 航遇项目react踩坑

    1.iconfont应用: a.正常用法如下 <span className='iconfont' > iconfont的代码,例如: </span> b.react不能动态 ...

  2. IAAS-libvirt介绍。

    Libvirt介绍 Libvirt与hypervisor无关,其提供与多种操作系统虚拟化能力进行交互的API与工具库. Libvirt提供了一个通用稳定的抽象层,可以安全的操作物理机上的虚拟机,同时为 ...

  3. 【ASP.NET Core】JSON Patch 使用简述

    JSON Patch 是啥玩意儿?不知道,直接翻译吧,就叫它“Json 补丁”吧.干吗用的呢?当然是用来修改 JSON 文档的了.那咋修改呢?比较常见有四大操作:AMRR. 咋解释呢? A—— Add ...

  4. Hbuilder之开发Python

    .开发之前,安装Python 3.6 在Mac上安装Python 如果你正在使用Mac,系统是OS X 10.8~10.10,那么系统自带的Python版本是2.7.要安装最新的Python 3.6, ...

  5. HTTP相关:TCP/IP、DNS

    最近在看HTTP的书,看得有点慢,而且断断续续的,很多东西看完就忘了.知识点多且零散,感觉要多看几遍才能消化. TCP/IP协议族按层次分为4层: 应用层: 应用层决定了向用户提供应用服务时通信的活动 ...

  6. JAVA Set 交集,差集,并集

    /** * Created by yuhui on 2017/7/11 0011. */ import java.util.HashSet; import java.util.Set; public ...

  7. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  8. 解决redis connection refused: connect无法连接redis

    环境 VM VirtualBox安装虚拟机CentOS 7 1.Redis.conf配置文件中 注释掉 bind 127.0.0.1 2.防火墙关闭(或添加可访问的端口,具体不在此描述) 最后一个坑 ...

  9. 解决Ubuntu系统下的VMware Workstation无法打开虚拟网络编辑器界面的问题

    本文由荒原之梦原创,原文链接:http://zhaokaifeng.com/?p=630 操作环境: Ubuntu 17 VMware 14 pro for Linux 问题描述: 我在Ubuntu ...

  10. Base64 image

    [前端攻略]:玩转图片Base64编码 什么是 base64 编码? 我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样 ...