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. 【踩坑】iconfont使用异常bug

    你见过html页面上'x'字符变成打印机图标么?一般人应该没有. -----------------------诡异bug----------------------- 今天测试报了一个bug,说页面 ...

  2. Python_正则表达式样例

    ''' 正则表达式是字符串处理的有力工具和技术,正则表达式使用预定义的特定模式去匹配一类具有共同特征的字符串, 主要用于字符串处理,可以快速.准确地完成复杂的查找.替换等处理要求. 正则表达式由元字符 ...

  3. 【转】Sentry--错误日志收集

    简介 Sentry是一个实时事件日志记录和汇集的日志平台,其专注于错误监控,以及提取一切事后处理所需的信息.他基于Django开发,目的在于帮助开发人员从散落在多个不同服务器上的日志文件里提取发掘异常 ...

  4. eclipse 创建maven web示例

    注意,以下所有需要建立在你的eclipse等已经集成配置好了maven了,没有的话需要安装maven. 一.创建项目 1.新建maven项目,如果不在上面,请到other里面去找一下 一直点击下一步, ...

  5. 【转】利用 force index优化sql语句性能

    今天写了一个统计sql,在一个近亿条数据的表上执行,200s都查不出结果.SQL如下: select customer,count(1) c from upv_** where created bet ...

  6. Intent里ACTION的CALL和DIAL的区别?

    Intent在进行activity之间的跳转的时候有一种方式是通过设置ACTION的方式来进行跳转的,这个ACTION是设置在manifest文件里Intent-filter里的,我们可以通过跳转自定 ...

  7. 错误 C2280 Union : 尝试引用已删除的函数 以及 警告 C4624 “Grade”: 已将析构函数隐式定义为“已删除”的一种解决方法

    Union 是C/C++语言中的一种结构类型,用于定义可共享内存的数据变量的一种方式,初次使用Union联合体时可能会遇到以下问题: 错误 C2280 Union : 尝试引用已删除的函数 警告 C4 ...

  8. c# xml操作(二)

    c# xml操作(二) 此博文包含图片 (-- ::)转载▼ 标签: 杂谈 分类: c# 上次,我们介绍了增加和删除xml的一些操作,这次我们将介绍如何更改和读取xml特定节点.我们依然以上次的xml ...

  9. 译MassTransit 创建消息消费者

    创建消息消费者一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型 public class UpdateCustomerConsumer ...

  10. 多线程动态规划算法求解TSP(Traveling Salesman Problem) 并附C语言实现例程

    TSP问题描述: 旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人要拜访n个城市,他必须 ...