Java基础-内部类与异常处理

ops/2024/11/26 3:01:53/

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

一、Java 内部类

什么是内部类?

使用内部类的优点

访问局部变量的限制

内部类和继承

内部类中没有静态成员 

生成的内部类的类文件

静态上下文中的内类

二、Java 内部类类型

成员内部类

局部内部类 

匿名内部类

三、Java 异常处理

try-catch块

Java 异常类 

异常类层次结构

使用多个catch块


一、Java 内部类

什么是内部类?

作为包的成员的类被称为顶级类。

一个类可以在另一个类中声明。这种类型的类称为内部类。

如果在另一个类中声明的类被显式或隐式声明为static,它被称为嵌套类,而不是内部类。

包含内部类的类称为封闭类或外部类。

下面的代码声明一个内部类。

java">class Outer {public class Inner {// Members of the Inner class go here}// Other members of the Outer class go here
}

Outer类是一个顶级类。

Inner类是一个内部类。它是外类的成员。

外层类是Inner类的封闭(外部)类。

内部类可以是另一个内部类的封闭类。内部类的嵌套层次没有限制。

内部类的实例只能存在于其封闭类的实例中。

使用内部类的优点

以下是内部类的一些优点。

  • 在将使用它们的其他类附近定义类。

  • 提供了一个额外的命名空间来管理类结构。

  • 一些设计模式使用内部类更容易实现。

  • 实现回调机制使用内部类是优雅和方便的。它有助于在Java中实现闭包。

访问局部变量的限制

下面的代码演示了访问局部内部类中的局部变量的规则。

main()方法声明两个局部变量x和y。这两个变量都是最终的。

变量x在被初始化之后从不改变,变量y不能被改变,因为它被声明为final。

java">public class Main {public static void main(String... args) {int x = 1;final int y = 2;class LocalInner {void print() {System.out.println("x = " + x);System.out.println("y = " + y);}}/** Uncomment the following statement will make the variable x no longer* an effectively final variable and the LocalIneer class will not compile.*/// x = 100;LocalInner li = new LocalInner();li.print();}
}

上面的代码生成以下结果

内部类和继承

内部类可以继承另一个内部类,顶级类或其封闭类。

java">class A {public class B {}public class C extends B {}public class D extends A {}
}class E extends A {public class F extends B {}
}

内部类中没有静态成员 

Java中的关键字static使一个构造成为一个顶层结构。

因此,我们不能为内部类声明任何静态成员(字段,方法或初始化器)。

允许在内部类中有作为编译时常量的静态字段。

java">class A {public class B {public final static int DAYS_IN_A_WEEK = 7; // OKpublic final String str = new String("Hello");}
}

生成的内部类的类文件

每个内部类都被编译成一个单独的类文件。

成员内部类和静态内部类的类文件名格式如下:

java"><outer-class-name>$<member-or-static-inner-class-name>

局部内部类的类文件名的格式如下:

java"><outer-class-name>$<a-number><local-inner-class-name>

匿名类的类文件名的格式如下:

java"><outer-class-name>$<a-number>

类文件名中的<a-number>是从1开始顺序生成的数字,以避免任何名称冲突。

静态上下文中的内类

java">class Outer {static int k = 1;int m = 2;public static void staticMethod() {// Class Inner is defined in a static contextclass Inner {int j = k; // OK. Referencing static field k// int n = m; // An error. Referencing non-static field m}}
}

二、Java 内部类类型

您可以在类中的任何位置定义内部类,您可以在其中编写Java语句。

有三种类型的内部类。内部类的类型取决于位置和声明的方式。

  • 成员内部类

  • 局部内部类

  • 匿名内部类

成员内部类

成员内部类在类中声明的方式与声明成员字段或成员方法相同。

它可以声明为public,private,protected或package-level。

成员内部类的实例可以仅存在于其封闭类的实例内。

以下代码创建了一个成员内部类。

java">class Car {private int year;// A member inner class named Tire publicclass Tire {private double radius;public Tire(double radius) {this.radius = radius;}public double getRadius() {return radius;}} // Member inner class declaration ends here// A constructor for the Car classpublic Car(int year) {this.year = year;}public int getYear() {return year;}
}

局部内部类 

局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

java">class People{public People() {}
}class Man{public Man(){}public People getWoman(){class Woman extends People{   //局部内部类int age =0;}return new Woman();}
}

匿名内部类

匿名内部类没有名称。因为它没有名称,它不能有一个构造函数。

匿名类是一次性类。您定义一个匿名类并同时创建它的对象。

创建匿名类及其对象的一般语法如下:

java">new Superclass(<argument-list-for-a-superclass-constructor>)  {
// Anonymous  class body  goes  here
}
java">new Interface()  {
// Anonymous  class body  goes  here
}

它后面是现有的接口名称或现有的类名称。

接口名称或类名称不是新创建的匿名类的名称。

如果使用接口名称,则匿名类实现接口。

如果使用类名,则匿名类继承自类。

仅当新运算符后面跟有类名时,才使用<argument-list>。如果新运算符后跟接口名称,则它为空。

如果<argument-list>存在,它包含要调用的现有类的构造函数的实际参数列表。

匿名类主体像往常一样在大括号中。

匿名类主体应该简短,以便更好的可读性。

下面的代码包含一个简单的匿名类,它在标准输出上打印一条消息。

java">public class Main {public static void main(String[] args) {new Object() {// An instance initializer{System.out.println("Hello from  an  anonymous class.");}}; // A semi-colon is necessary to end the statement}
}

上面的代码生成以下结果

三、Java 异常处理

异常是在没有定义正常执行路径时在Java程序的执行期间可能出现的条件。

Java通过将执行操作的代码与处理错误的代码分离来处理错误。

当发生异常时,Java会创建一个包含有关异常的所有信息的对象,并将其传递给相应的异常处理代码。

有关异常的信息包括异常的类型,发生异常的代码中的行号等。

try-catch块

要处理异常,请将代码放在try块中。try块如下所示:

java">try  {// Code for the try block
}

try块以关键字try开头,后面是开括号和结束括号。

try块的代码放在开口和关闭大括号内。

try块本身不能使用。

它必须后跟一个或多个catch块,或一个finally块,或两者的组合。

要处理可能在try块中抛出的异常,请使用catch块。

一个catch块可用于处理多种类型的异常。

catch块的语法与方法的语法相似。

java">catch (ExceptionClassName parameterName)   {// Exception handling  code
}

catch块的声明就像一个方法声明。

它从关键字catch开始,后面跟一对括号。

在括号中,它声明了一个参数。

参数类型是应该捕获的异常类的名称。

parameterName是用户给定的名称。括号后面是开口括号和结束括号。异常处理代码放在大括号中。

当抛出异常时,异常对象的引用将复制到parameterName。

我们可以使用parameterName从异常对象中获取信息。

我们可以将一个或多个catch块与try块关联。

try-catch块的一般语法如下。

java">try  {// Your code  that may throw  an  exception
}
catch  (ExceptionClass1 e1){// Handle  exception of  ExceptionClass1 type
}
catch  (ExceptionClass2 e2){// Handle  exception of  ExceptionClass2 type
}
catch  (ExceptionClass3 e3){// Handle  exception of  ExceptionClass3 type
}

 例子

下面的代码显示了如何处理除零异常。

java">public class Main {public static void main(String[] args) {int x = 10, y = 0, z;try {z = x / y;System.out.println("z = " + z);} catch (ArithmeticException e) {String msg = e.getMessage();System.out.println("The error is: " + msg);}System.out.println("The end.");}
}

上面的代码生成以下结果

Java 异常类 

异常类层次结构

异常类层次结构从java.lang.Throwable类开始。

当抛出异常时,它必须是Throwable类的对象或其任何子类。

catch块的参数必须是Throwable类型,或其子类之一,例如Exception,ArithmeticException,IOException等。

我们可以通过从一个异常类继承我们的类来创建我们自己的异常类。

使用多个catch块

Java运行时选择适当的catch块,并从第一个catch块开始顺序寻找合适的catch时钟。

try块的多个catch块必须从最具体的异常类型排列为最通用的异常类型。

以下代码使用多个catch块的有效序列。

ArithmeticException类是RuntimeException类的子类。

如果这两个异常都在同一个try块的catch块中处理,那么最具体的类型,即ArithmeticException,必须出现在最通用的类型之前,即RuntimeException。

java">try  {
// Do  something, which  might  throw  Exception
}
catch(ArithmeticException e1)  {
// Handle  ArithmeticException first
}
catch(RuntimeException e2)  {
// Handle  RuntimeException after  ArithmeticException
}

http://www.ppmy.cn/ops/136736.html

相关文章

【JavaEE初阶 — 多线程】定时器的应用及模拟实现

目录 1. 标准库中的定时器 1.1 Timer 的定义 1.2 Timer 的原理 1.3 Timer 的使用 1.4 Timer 的弊端 1.5 ScheduledExecutorService 2. 模拟实现定时器 2.1 实现定时器的步骤 2.1.1 定义类描述任务 定义类描述任务 第一种定义方法 …

Linux ntp时间服务部署

本文使用云服务器&#xff0c;系统是Ubuntu 20.04 LTS&#xff0c;以下操作都是在Ubuntu上面执行的&#xff01;&#xff01; 一、Linux系统时间命令 timedatectl命令 timedatectl 是现代 Linux 系统中最强大的时间管理命令&#xff0c;特别是对于使用 systemd 的系统。它不仅…

显示类控件

文章目录 1 QLabel1.1 常用属性1.2 例子1&#xff0c;设置文本 (textFormat)1.3 例子2&#xff0c;设置widget背景图片 (pixmap和scaledContents)1.4 例子3&#xff0c;设置对齐方式 (alignment)1.5 例子4&#xff0c;设置自动换行&#xff0c;缩进和边距1.5.1 设置换行 (wordW…

大连环保公益管理系统|Java|SSM|Vue| 前后端分离

【重要①】前后端源码万字文档部署文档 【重要②】正版源码有问题包售后 【包含内容】 【一】项目提供非常完整的源码注释 【二】相关技术栈文档 【三】源码讲解视频 【其它服务】 【一】可以提供远程部署安装&#xff0c;包扩环境 【…

linux从0到1——shell编程9

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

双因子认证:统一运维平台安全管理策略

01双因子认证概述 双因子认证&#xff08;Two-Factor Authentication&#xff0c;简称2FA&#xff09;是一种身份验证机制&#xff0c;它要求用户提供两种不同类型的证据来证明自己的身份。这通常包括用户所知道的&#xff08;如密码&#xff09;、用户所拥有的&#xff08;如…

【数据结构 | C++】并查操作

现在有一个并查集&#xff0c;你需要完成合并和查询操作。 输入格式: 第一行包含两个整数 N,M ,表示共有 N 个元素和 M 个操作。 接下来 M 行&#xff0c;每行包含三个整数 zi,xi,yi 。 当 zi1 时&#xff0c;将 xi与yi所在的集合合并。 当 zi2 时&#xff0c;输出xi与yi 是否…

【AIGC】破解ChatGPT!如何使用高价值提示词Prompt提升响应质量

文章目录 为什么高价值提示词如此重要&#xff1f;&#x1f50d;1.1 提升响应的相关性和准确性1.2 节省时间与资源1.3 增强用户体验 了解ChatGPT的工作原理&#x1f9e0;2.1 语言模型的训练过程2.2 上下文理解与生成2.3 限制与挑战 高价值提示词的核心要素✍️3.1 清晰明确的指…