学习笔记:黑马程序员Java 您所在的位置:网站首页 黑马程序员老板是谁 学习笔记:黑马程序员Java

学习笔记:黑马程序员Java

2024-06-21 09:33| 来源: 网络整理| 查看: 265

Java语言入门到精通章节

学习笔记:Java-基础篇(第一部分)_ljtxy.love的博客-CSDN博客学习笔记:Java-中级篇(第二部分)_ljtxy.love的博客-CSDN博客学习笔记:Java-高级篇(第三部分)_ljtxy.love的博客-CSDN博客学习笔记:Java-进阶篇(一)(第四部分)_ljtxy.love的博客-CSDN博客学习笔记:Java-进阶篇(二)(第五部分)_ljtxy.love的博客-CSDN博客学习笔记:Java8新特性_ljtxy.love的博客-CSDN博客

文章目录 1.概述1.1定义1.2特点1.3三大版本1.3.1JavaSE标准版1.3.2JavaME微型版1.3.3JavaEE企业版 1.3JDK安装1.3.1概述1.3.2基本用例 2.基本用例-HelloWorld3.基础语法3.1注释3.1.1概述3.1.2分类 3.2关键字3.2.1概述3.2.2分类3.2.3基本用例-关键字演示 3.3字面量3.3.1概述3.3.2分类3.3.3基本用例 3.4变量3.4.1概述3.4.2格式3.4.3基本用例-变量演示 3.5数据类型3.5.1概述3.5.2分类3.5.3基本数据类型3.5.4引用数据类型3.5.5基本数据类型和引用数据类型区别3.5.6常用的数据类型 3.6标识符3.6.1硬性要求3.6.2软性建议3.6.3阿里巴巴命名规范细节 3.7权限修饰符3.7.1概述3.7.2权限访问能力3.7.3权限使用规则 3.8包3.8.1概述3.8.2导包 4.IDEA开发工具4.1概述4.2安装4.3目录层级结构3.4.1概述4.3.2项目、工程(project)4.3.2模块(module)4.3.3包(package)4.3.4类(class) 4.4常用配置4.5类的相关操作4.6模块的相关操作4.7项目的相关操作4.8插件管理 5.运算符和表达式5.0概述5.0.1定义5.0.2运算符5.0.3表达式 5.1算术运算符5.1.1概述5.1.1.1定义5.1.1.2分类5.1.1.3特点 5.1.2基本用例-运算符演示5.1.3案例-数值拆分 5.2自增自减运算符5.2.1概述5.2.1.1定义5.2.1.2分类5.2.1.3特点 5.2.2基本用例-自增自减演示 5.3赋值运算符5.3.1概述5.3.2基本用例-赋值运算符演示 5.4扩展赋值运算符4.4.1概述4.4.1.15.4.1.2分类4.5.1.3特点 5.4.2基本用例-扩展运算符演示 5.5关系运算符5.5.1定义5.5.2分类 5.6逻辑运算符5.6.1概述5.6.1.1定义5.6.1.2& 和 | 的使用 5.6.2基本用例-逻辑运算符演示5.6.3应用场景5.6.3.1场景举例5.6.3.2^(异或)的使用5.6.3.3!(取反)的使用 5.7短路逻辑运算符5.7.1概述5.7.1.1定义5.7.1.2分类 5.7.2应用场景5.7.2.1场景5.7.2.2总结5.7.2.3建议 5.8三元运算符5.8.1概述5.8.1.1定义5.8.1.2格式 5.8.2基本用例-三元运算符演示 5.9运算符的优先级5.10隐式转换5.10.1定义5.10.2提升规则5.10.3取值范围关系 5.11强制转换5.11.1概念5.11.1.1定义5.11.1.2格式 5.11.2基本用例-轻质转换演示 5.12中字符的+操作5.12.1概念5.12.2基本用例-字符+演示 5.13位移运算符 6.控制语句6.1概述6.1.1定义6.1.2分类 6.1流程控制语句6.1.1概述6.1.1.1定义6.1.1.2分类 6.1.1顺序结构6.1.1.1定义6.1.1.2执行流程图 6.1.2判断结构--f语句6.1.3选择结构--switch语句6.1.4循环结构6.1.4.1for循环结构(掌握)6.1.4.2while循环6.1.4.3do...while循环6.1.4.4三种格式的区别6.1.4.4无限循环 6.2条件控制语句6.2.1break6.2.2continue 7.数组7.1概述7.1.1定义7.1.2建议 7.2数组定义7.2.1格式一7.2.2格式二 7.3数组的静态初始化7.4数组的动态初始化7.5地址值7.6索引7.6.1定义7.6.2特点 7.7数组元素访问7.7.1作用7.7.2基本用例-数组访问演示 7.8数组的遍历7.8.1遍历7.8.2基本用例-数组遍历演示 7.9数组两种初始化方式的区别7.9.1静态初始化7.9.2动态初始化7.9.3应用场景7.9.4数组常见问题 8.代码块8.1局部代码块8.2构造代码块8.3静态代码块(重点) 9.关键字9.1this关键字9.2static关键字9.2.1概述9.2.1静态变量及其访问9.2.1.1概述9.2.1.2基本用例-static关键字使用9.2.1.3访问 9.2.2实例变量及其访问9.2.2.1概述9.2.2.2基本用例-实例变量使用9.2.2.3访问 9.2.3静态方法及其访问9.2.3.1概述9.2.3.2基本用例9.2.3.2访问 9.2.4实例方法及其访问9.2.4.1概述9.2.4.2基本用例-实例方法使用9.2.4.3访问 9.2.5Static内存图(重点)9.2.6Static修饰成员变量和成员方法9.2.7工具类常用Static9.2.8Static弊端 9.3final关键字9.3.1概述9.3.2修饰变量9.3.2.1局部变量(重点)9.3.2.2成员变量(重点) 9.3.3修饰方法9.3.3.1概述9.3.3.2基本用例-修饰方法演示 9.3.4修饰类9.3.4.1概述9.3.4.2基本用例-修饰类使用 9.4private关键字9.4.1概述9.4.2基本用例-private关键字使用9.4.3案例-private的使用 9.5this关键字9.6super关键字9.6.1概述9.6.3基本用例-super关键字使用9.6.4内存图9.6.5this( )基本用例 知识加油篇1.Java内存模型2.Idea快捷键2.1查看接口实现类2.2图标小细节 3.int 和Integer 区别4.String 和Character 区别5.基本数据类型和引用数据类型的区别

1.概述

笔记小结:

定义:Java是一种高级语言。它被设计为一种通用的、面向对象的编程语言,具有跨平台性和可移植性特点:简单易学、面向对象编程、平台无关性、安全性、高性能、多线程支持、开源免费跨平台原理:针对于不同的操作系统,Java提供了不同的虚拟机,对于不同的操作系统,安装不同的虚拟机三大版本: JavaSE:SE即标准版,包含了Java核心类库,主要用来开发桌面应用JavaME:ME即微型版,包含了SE中部分类库,又有自己扩展部分,主要用来做移动类嵌入式开发JavaEE:EE即企业版,包含SE,又有扩展部分(Servlet,JDBC等),主要用来开发分布式网络程序 JRE、JVM、JDK: JVM(Java Virtual Machine),Java虚拟机JRE(Java Runtime Environment),Java运行环境,包含了JVM和Java的核心类库(Java API)JDK(Java Development Kit)称为Java开发工具,包含了JRE和开发工具 下载和安装目录介绍环境变量配置 1.1定义

​ Java是一种广泛使用的计算机编程语言,由Sun Microsystems(后来被Oracle收购)在1995年推出。它被设计为一种通用的、面向对象的编程语言,具有跨平台性和可移植性

补充:

语言:人与人交流沟通的表达方式

计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言

1.2特点 简单易学:Java采用类似于C++的语法,但它去除了一些容易导致错误的复杂特性,使得它更加简单易学。面向对象编程:Java是一种完全面向对象编程语言,这意味着所有的程序元素都是对象,通过对象之间的交互实现程序的逻辑。跨平台性:Java程序在不同平台上可以运行,这是因为Java程序通过JVM(Java虚拟机)来运行,JVM能够在不同平台上执行相同的Java代码。安全性:Java是一种安全性较高的编程语言,因为它具有内置的安全机制,如内存管理、异常处理和访问控制。高性能:尽管Java是一种解释型语言,但它可以通过JIT(即时编译)技术提高性能。多线程支持:Java提供了内置的多线程支持,使得程序员可以很方便地编写多线程程序。开源免费:Java是一种开源免费的编程语言,可以通过许多渠道获得它的开发工具和运行环境。

Java语言跨平台的原理

操作系统本身其实是不认识Java语言的。但是针对于不同的操作系统,Java提供了不同的虚拟机。

在这里插入图片描述

image-20230227102000755

1.3三大版本

​ JavaSE、JavaME、JavaEE

1.3.1JavaSE标准版

​ JavaSE(Java Platform, Standard Edition),Java语言的(标准版),用于桌面应用的开发,是其他两个版本的基础。

1.3.2JavaME微型版

​ JavaME(Java Platform, Micro Edition),Java语言的小型版,用于嵌入式消费类电子设备或者小型移动设备的开发。(嵌入式,电视机,微波炉,电视机等),其中最为主要的还是小型移动设备的开发(手机)。渐渐的没落了,已经被安卓和IOS给替代了。但是,安卓也是可以用Java来开发的。

1.3.3JavaEE企业版

​ JavaEE(Java Platform, Enterprise Edition)用于Web方向的网站开发。(主要从事后台服务器的开发)在服务器领域,Java是当之无愧的龙头老大。

在这里插入图片描述

1.3JDK安装 1.3.1概述 JVM(Java Virtual Machine),Java虚拟机JRE(Java Runtime Environment),Java运行环境,包含了JVM和Java的核心类库(Java API)JDK(Java Development Kit)称为Java开发工具,包含了JRE和开发工具

在这里插入图片描述

说明:

​ 当我们开发时,我们只需安装JDK即可,它包含了java的运行环境和虚拟机。当我们只运行时只需要装JRE即可

1.3.2基本用例

说明:

通过官方网站获取JDK,网址:Java Downloads | Oracle 中国

注意:

安装路径不要有中文,不要有空格等一些特殊的符号。以后跟开发相关的所有软件建议都安装在同一个文件夹中,方便管理。

步骤一:下载JDK 在这里插入图片描述

补充:安装目录

在这里插入图片描述

以上是JDK17的安装目录,以下是JDK的目录解释 目录名称说明bin该路径下存放了JDK的各种工具命令。javac和java就放在这个目录。conf该路径下存放了JDK的相关配置文件。include该路径下存放了一些平台特定的头文件。jmods该路径下存放了JDK的各种模块。legal该路径下存放了JDK各模块的授权文档。lib该路径下存放了JDK工具的一些补充JAR包。

步骤二:环境变量配置

说明:

​ 开发Java程序,需要使用JDK提供的开发工具(比如javac.exe、java.exe等命令),而这些工具在JDK的安装目录的bin目录下,如果不配置环境变量,那么这些命令只可以在bin目录下使用,而我们想要在任意目录下都能使用,所以就要配置环境变量

1.配置JAVA_HOME环境

image-20230809140945961

2.配置PATH环境

在这里插入图片描述

补充:

JAVA_HOME:告诉操作系统JDK安装在了哪个位置(未来其他技术要通过这个找JDK)Path:告诉操作系统JDK提供的javac(编译)、java(执行)命令安装到了哪个位置

步骤三:演示

新建cmd命名窗口,输入java --version

image-20230809141449697

说明:

​ 此处可以看到JDK的版本为17

2.基本用例-HelloWorld

笔记小结:

​ Java程序开发运行流程需要三个步骤:编写程序,编译程序,运行程序

说明:

​ 通过HelloWorld程序演示Java流程基本执行流程

步骤一:创建Java程序

新建HelloWorld.class文件,并编写 class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }

步骤二:编译Java程序

说明:

​ javac 是 Java 编译器的命令行工具,用于将 Java 源代码文件(以 .java 扩展名结尾)编译成 Java 字节码文件(以 .class 扩展名结尾)。Java 字节码文件可以在Java虚拟机(JVM)上运行。

打开命令行窗口执行javac命令 javac HelloWorld.java

说明:结果

在这里插入图片描述

步骤三:执行字节码文件

打开命令行窗口执行当前目录下java命令 java HelloWorld

说明:结果

在这里插入图片描述

注意:

​ 运行class文件时,不需要加.class后缀

3.基础语法

笔记小结:

注释:单行注释、多行注释、文档注释

关键字:

定义:被Java赋予了特定含义的英文单词class、static、……

字面量:

定义:数据在程序中的书写格式666、”MySoul“、……

变量:

定义:临时存储数据的容器int a = 16;、double b = 10.1;、……注意:Java中变量需要有变量类型、变量名以及分号结束

数据类型:

基本数据类型:byte、short、int、long、float、double、char和boolean引用数据类型:字符串、数组、类和接口、……区别: 基本数据类型存储在栈中,而引用数据类型存储在堆中基本数据类型的变量之间是相互独立的,而引用数据类型的变量之间可能共享同一个对象

标识符:

定义:标识符是用来命名变量、方法、类、接口等程序元素的名称注意: 必须由数字、字母、**下划线_、美元符号$**组成。数字不能开头不能是关键字区分大小写的 阿里巴巴命名规范细节

权限修饰符:

定义:权限修饰符是Java中的一种关键字,用于控制类、方法和变量的访问权限权限范围:private public static void main(String[] args) { System.out.println(10); // 输出一个整数 System.out.println(5.5); // 输出一个小数 System.out.println('a'); // 输出一个字符 System.out.println(true); // 输出boolean值true System.out.println("欢迎来到黑马程序员"); // 输出字符串 } }

补充:区分技巧

不带小数点的数字都是整数类型的字面量只要带了小数点,那么就是小数类型的字面量只要用双引号引起来的,不管里面的内容是什么,不管里面有没有内容,都是字符串类型的字面量。字符类型的字面量必须用单引号引起来,不管内容是什么,但是个数有且只能有一个布尔类型的字面量只有两个值,true、false空类型的字面量只有一个值,null 3.4变量 3.4.1概述

​ 变量就在程序中临时存储数据的容器。但是这个容器中只能存一个值。

3.4.2格式 数据类型 变量名 = 数据值;

说明:

如果要存10,那么数据类型就需要写整数类型。

如果要存10.0,那么数据类型就需要写小数类型。

补充:参数解释

变量名:其实就是这个容器的名字

数据值:真正存储在容器中的数据

分号:表示语句的结束,就跟以前写作文时候的句号是一样的

3.4.3基本用例-变量演示 public class VariableDemo2{ public static void main(String[] args){ //1.变量名不允许重复 //int a = 10; //int a = 20; //System.out.println(a); //2.一条语句可以定义多个变量 //了解。 //int a = 10, b = 20, c = 20,d = 20; //System.out.println(a);//? //System.out.println(b);//? //3.变量在使用之前必须要赋值 int a = 30; System.out.println(a); } }

注意:

变量名不能重复在一条语句中,可以定义多个变量。但是这种方式影响代码的阅读,所以了解一下即可。变量在使用之前必须要赋值。 3.5数据类型 3.5.1概述

​ Java 数据类型是用来定义变量或表达式可以存储的数据类型的分类

3.5.2分类 基本数据类型引用数据类型(面向对象的时候再深入学习) 3.5.3基本数据类型 整数类型(Integer Types):byte:8位,范围为 -128 到 127、short:16位,范围为 -32,768 到 32,767、int:32位,范围为 -2^31 到 2^31 - 1、long:64位,范围为 -2^63 到 2^63 - 1浮点类型(Floating-Point Types):float:32位,用于表示单精度浮点数、double:64位,用于表示双精度浮点数字符类型(Character Type):char:16位,用于存储一个 Unicode 字符布尔类型(Boolean Type):boolean:用于表示布尔值,只有两个取值:true 和 false

注意:

byte类型的取值范围: -128 ~ 127int类型的大概取值范围: -21亿多 ~ 21亿多

补充:整数类型和小数类型的取值范围大小关系:

double > float > long > int > short > byte在java中整数默认是int类型,浮点数默认是double类型

代码示例:

public class VariableDemo3{ public static void main(String[] args){ //1.定义byte类型的变量 //数据类型 变量名 = 数据值; byte a = 10; System.out.println(a); //2.定义short类型的变量 short b = 20; System.out.println(b); //3.定义int类型的变量 int c = 30; System.out.println(c); //4.定义long类型的变量 long d = 123456789123456789L; System.out.println(d); //5.定义float类型的变量 float e = 10.1F; System.out.println(e); //6.定义double类型的变量 double f = 20.3; System.out.println(f); //7.定义char类型的变量 char g = 'a'; System.out.println(g); //8.定义boolean类型的变量 boolean h = true; System.out.println(h); } }

注意:

如果要定义 一个整数类型的变量,不知道选择哪种数据类型了,默认使用int。如果要定义 一个小数类型的变量,不知道选择哪种数据类型了,默认使用double。如果要定义一个long类型的变量,那么在数据值的后面需要加上L后缀。(大小写都可以,建议大写。)如果要定义一个float类型的变量,那么在数据值的后面需要加上F后缀。(大小写都可以) 3.5.4引用数据类型 类(Class):类是用来创建对象的模板。它定义了对象的属性(成员变量)和方法(成员方法)。通过实例化类,可以创建类的对象,并使用对象调用类的方法。接口(Interface):接口定义了一组方法的规范,但没有实际的方法体。类可以实现一个或多个接口,从而获得接口定义的方法,并在类中实现这些方法。数组(Array):数组是一种用于存储相同类型元素的数据结构。它可以是一维数组或多维数组,用于在内存中连续存储多个元素。枚举(Enum):枚举是一种特殊的类,用于表示一组预定义的常量。枚举常常用于表示一组相关的值。字符串(String):字符串是一种引用数据类型,但它具有特殊的性质,可以像基本数据类型一样进行操作。字符串实际上是一个字符序列,它有许多方法用于处理字符串操作。自定义引用类型:除了上述内置的引用数据类型,开发人员还可以创建自定义的类和接口,以及它们的实例,从而构建更复杂的数据结构和功能。 3.5.5基本数据类型和引用数据类型区别 基本数据类型:基本数据类型是按值传递的,它们在Java虚拟机栈中分配内存空间,并直接存储值本身。当基本数据类型的变量被赋值时,实际上是将该变量中的值复制到另一个变量中,这两个变量之间没有任何关联。引用数据类型:引用数据类型是按引用传递的,它们在Java虚拟机堆中分配内存空间,存储的是对象的引用(内存地址)。当引用数据类型的变量被赋值时,实际上是将该变量中的引用复制到另一个变量中,这两个变量指向同一个对象。

补充:

​ 详细请参考知识加油站站基本数据类型和引用数据类型区别

代码示例:

// 使用引用数据类型创建一个对象 String message = new String("Hello, World!"); // 创建一个数组 int[] numbers = new int[5]; // 使用自定义类创建对象 class Person { String name; int age; } Person person = new Person(); person.name = "Alice"; person.age = 30; // 枚举类型 enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } Day today = Day.WEDNESDAY; 3.5.6常用的数据类型 ​ 整数:int​ 小数:(浮点数)double

代码示例:

public class VariableDemo{ public static void main(String[] args){ //定义一个整数类型的变量 //数据类型 变量名 = 数据值; int a = 16; System.out.println(a);//16 //定义一个小数类型的变量 double b = 10.1; System.out.println(b);//10.1 } }

补充:

​ null不能直接打印的,如果需要打印需要用字符串的形式进行打印。

最为常用的数据类型选择:

在定义变量的时候,要根据实际的情况来选择不同类型的变量。

比如:人的年龄,可以选择byte类型

比如:地球的年龄,可以选择long类型

如果整数类型中,不太确定范围,那么默认使用int类型

如果小数类型中,不太确定范围,那么默认使用double类型

如果要定义字符类型的变量,那么使用char

如果要定义布尔类型的变量,那么使用boolean

3.6标识符

​ 在Java中,标识符是用来标识程序中各种元素的名称,比如变量、方法、类、接口等。标识符是由字母、数字、下划线(_)和美元符号($)组成的序列,且必须以字母、下划线或美元符号开头。标识符在编程中用于命名各种实体,使得程序易于阅读、理解和维护

3.6.1硬性要求

​ 必须要这么做,否则代码会报错。

必须由数字、字母、下划线_、**美元符号$**组成。数字不能开头不能是关键字区分大小写的。 3.6.2软性建议

1.小驼峰命名法

适用于变量名和方法名

如果是一个单词,那么全部小写,比如:name

如果是多个单词,那么从第二个单词开始,首字母大写,比如:firstName、maxAge

2.大驼峰命名法

适用于类名

如果是一个单词,那么首字母大写。比如:Demo、Test。

如果是多个单词,那么每一个单词首字母都需要大写。比如:HelloWorld

3.6.3阿里巴巴命名规范细节

尽量不要用拼音。但是一些国际通用的拼音可视为英文单词。

正确:alibaba、hangzhou、nanjing

错误:jiage、dazhe

平时在给变量名、方法名、类名起名字的时候,不要使用下划线或美元符号。

错误:_name

正确:name

3.7权限修饰符 3.7.1概述

​ 在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,我们之前已经学习过了public 和 private,接下来我们研究一下protected和默认修饰符的作用。

public:公共的,所有地方都可以访问。

protected:本类 ,本包,其他包中的子类都可以访问。

默认(没有修饰符):本类 ,本包可以访问。

注意:默认是空着不写,不是default

private:私有的,当前类可以访问。 public > protected > 默认 > private

3.7.2权限访问能力

权限范围

private //1.最为简单的赋值运算符用法 int a = 10;//就是把10赋值给变量a System.out.println(a); //2.如果等号右边需要进行计算。 int b = 20; int c = a + b;//先计算等号右边的,把计算的结果赋值给左边的变量 System.out.println(c); //3.特殊的用法 a = a + 10;//先计算等号右边的,把计算的结果赋值给左边的变量 System.out.println(a);//20 } } 5.4扩展赋值运算符 4.4.1概述 4.4.1.1

​ 扩展赋值运算符是指在原有的赋值运算符基础上加上其他算数运算符,例如 +=, -=,*= 等等

5.4.1.2分类

​ +=、-=、*=、/=、%=

4.5.1.3特点

​ 就是把左边跟右边进行运算,把最终的结果赋值给左边,对右边没有任何影响。

5.4.2基本用例-扩展运算符演示 public class OperatorDemo7 { public static void main(String[] args) { //扩展赋值运算符 int a = 10; int b = 20; a += b;//把左边和右边相加,再把最终的结果赋值给左边,对右边没有任何影响 // 相当于 a = a + b; System.out.println(a);//30 System.out.println(b);//20 } }

注意:

扩展的赋值运算符中隐层还包含了一个强制转换

例如:

public class OperatorDemo8 { public static void main(String[] args) { byte a = 10; byte b = 20; //a += b; a = (byte)(a + b); System.out.println(a);//30 } }

说明:以+=为例。a += b ;实际上相当于 a = (byte)(a + b);

5.5关系运算符 5.5.1定义

​ 又叫比较运算符,其实就是拿着左边跟右边进行了判断而已。

5.5.2分类 符号解释==就是判断左边跟右边是否相等,如果成立就是true,如果不成立就是false!=就是判断左边跟右边是否不相等,如果成立就是true,如果不成立就是false>就是判断左边是否大于右边,如果成立就是true,如果不成立就是false>=就是判断左边是否大于等于右边,如果成立就是true,如果不成立就是false //需求:求两个数的较大值 int a = 10; int b = 20; //格式:关系表达式 ? 表达式1 : 表达式2 ; //注意点: //三元运算符的最终结果一定要被使用。 //要么赋值给一个变量,要么直接输出。 int max = a > b ? a : b ; System.out.println(max); System.out.println(a > b ? a : b); } } 5.9运算符的优先级

​ 在Java中涉及了很多的运算符,每一种运算符都有各自的优先级。但是这些优先级不需要记忆。咱们只要知道其中一点:小括号优先于所有

5.10隐式转换 5.10.1定义

​ 在Java中,隐式转换就是把一个取值范围小的数据或者变量,赋值给另一个取值范围大的变量。此时不需要我们额外写代码单独实现,是程序自动帮我们完成的。也叫自动类型提升。换句话说,就是小的范围数据类型可以给大的范围数据类型,可以直接给

5.10.2提升规则 取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算。byte、short、char三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算。 5.10.3取值范围关系

​ byte < short < int < long < float < double

5.11强制转换 5.11.1概念 5.11.1.1定义

​ 如果要把一个取值范围大的数据或者变量赋值给另一个取值范围小的变量。是不允许直接操作。

5.11.1.2格式

​ 目标数据类型 变量名 = (目标数据类型)被强转的数据;

5.11.2基本用例-轻质转换演示 public class OperatorDemo2 { public static void main(String[] args) { double a = 12.3; int b = (int) a; System.out.println(b);//12 } }

注意点:

​ 强制转换有可能会导致数据发生错误。(数据的精度丢失)

5.12中字符的+操作 5.12.1概念

​ 当+操作中出现了字符,会拿着字符到计算机内置的ASCII码表中去查对应的数字,然后再进行计算。

5.12.2基本用例-字符+演示 char c = 'a'; int result = c + 0; System.out.println(result);//97

说明:

ASCII码表中:

‘a’ ----- 97

‘A’ ----- 65

5.13位移运算符

​ 在Java中,位移运算符是一种操作二进制位的运算符,它可以对整数类型的数据进行位移操作。Java提供了三种位移运算符:左移(),无符号右移(>>>)

左移(> b 表示将a的二进制表示向右移动b位。无符号右移(>>>):将一个数的二进制表示向右移动指定的位数,无论最高位的符号位是什么,都用零填充。无符号右移操作会将符号位当作普通位处理,因此适用于无符号数的位移操作

​ 这些位移运算符在处理整数的二进制位时非常有用,常用于位操作、位标志的设置和清除,以及优化特定的算法。请注意,位移运算符仅适用于整数类型(如int、long等),不适用于浮点数类型。

6.控制语句

笔记小结:

流程控制语句

顺序结构:

含义:按照编写顺序依次执行的结构

判断和选择结构

含义:根据条件的不同而选择执行不同代码块的结构

例如:

if、switch

循环结构

含义:重复执行某段代码的结构

例如:

while、do…while、for

循环间的区别:1.for和while循环,是先判断,再执行。2.do…while是先执行,再判断

条件控制语句

含义:是一种程序控制结构,用于基于某些条件来执行或跳过代码块

例如:

break、continue

注意:条件控制语句在非循环结构中,不能使用

6.1概述 6.1.1定义

​ Java控制语句是用于控制程序流程执行的语句,它们可以根据条件或循环来改变程序的执行顺序。控制语句可以帮助你实现不同的条件逻辑和循环结构,从而实现不同的任务和功能。

6.1.2分类

​ Java控制语句分为:流程控制语句、条件控制语句

6.1流程控制语句 6.1.1概述 6.1.1.1定义

​ 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能

6.1.1.2分类

顺序结构

判断和选择结构(if, switch)

循环结构(for, while, do…while)

6.1.1顺序结构 6.1.1.1定义

​ 顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的

6.1.1.2执行流程图

1545615769372

6.1.2判断结构–f语句 if语句格式1 格式: if (关系表达式) { 语句体; }

执行流程:

①首先计算关系表达式的值

②如果关系表达式的值为true就执行语句体

③如果关系表达式的值为false就不执行语句体

④继续执行后面的语句内容

1545616039363

示例:

public class IfDemo { public static void main(String[] args) { System.out.println("开始"); //定义两个变量 int a = 10; int b = 20; //需求:判断a和b的值是否相等,如果相等,就在控制台输出:a等于b if(a == b) { System.out.println("a等于b"); } //需求:判断a和c的值是否相等,如果相等,就在控制台输出:a等于c int c = 10; if(a == c) { System.out.println("a等于c"); } System.out.println("结束"); } } f语句格式2 格式: if (关系表达式) { 语句体1; } else { 语句体2; }

执行流程:

①首先计算关系表达式的值

②如果关系表达式的值为true就执行语句体1

③如果关系表达式的值为false就执行语句体2

④继续执行后面的语句内容

1545616221283

示例:

public class IfDemo02 { public static void main(String[] args) { System.out.println("开始"); //定义两个变量 int a = 10; int b = 20; //需求:判断a是否大于b,如果是,在控制台输出:a的值大于b,否则,在控制台输出:a的值不大于b if(a > b) { System.out.println("a的值大于b"); } else { System.out.println("a的值不大于b"); } System.out.println("结束"); } }

if语句格式3

格式: if (关系表达式1) { 语句体1; } else if (关系表达式2) { 语句体2; } … else { 语句体n+1; }

执行流程:

①首先计算关系表达式1的值

②如果值为true就执行语句体1;如果值为false就计算关系表达式2的值

③如果值为true就执行语句体2;如果值为false就计算关系表达式3的值

④…

⑤如果没有任何关系表达式为true,就执行语句体n+1。

1545616667104

6.1.3选择结构–switch语句

格式

switch (表达式) { case 1: 语句体1; break; case 2: 语句体2; break; ... default: 语句体n+1; break; }

执行流程:

首先计算出表达式的值

其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。

最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。

default的位置和省略情况

default可以放在任意位置,也可以省略

case穿透

不写break会引发case穿透现象

switch在JDK12的新特性

int number = 10; switch (number) { case 1 -> System.out.println("一"); case 2 -> System.out.println("二"); case 3 -> System.out.println("三"); default -> System.out.println("其他"); } switch和if第三种格式各自的使用场景

当我们需要对一个范围进行判断的时候,用if的第三种格式

当我们把有限个数据列举出来,选择其中一个执行的时候,用switch语句

比如:

​ 小明的考试成绩,如果用switch,那么需要写100个case,太麻烦了,所以用if简单。

​ 如果是星期,月份,客服电话中0~9的功能选择就可以用switch

6.1.4循环结构 6.1.4.1for循环结构(掌握)

​ 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复 执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形 成死循环。

for循环格式:

for (初始化语句;条件判断语句;条件控制语句) { 循环体语句; }

格式解释:

初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去

执行流程:

①执行初始化语句

②执行条件判断语句,看其结果是true还是false

​ 如果是false,循环结束

​ 如果是true,继续执行

③执行循环体语句

④执行条件控制语句

⑤回到②继续

for循环书写技巧:

确定循环的开始条件确定循环的结束条件确定循环要重复执行的代码

代码示例:

//1.确定循环的开始条件 //2.确定循环的结束条件 //3.确定要重复执行的代码 //需求:打印5次HelloWorld //开始条件:1 //结束条件:5 //重复代码:打印语句 for (int i = 1; i 循环体; 条件控制语句; } 6.1.4.3do…while循环

本知识点了解即可

格式:

初始化语句; do{ 循环体; 条件控制语句; }while(条件判断语句);

特点:

​ 先执行,再判断。

6.1.4.4三种格式的区别

​ for和while循环,是先判断,再执行。

​ do…while是先执行,再判断。

​ 当知道循环次数或者循环范围的时候,用for循环。

​ 当不知道循环次数,也不知道循环范围,但是知道循环的结束条件时,用while循环。

6.1.4.4无限循环

概念:

​ 又叫死循环。循环一直停不下来。

for格式:

for(;;){ System.out.println("循环执行一直在打印内容"); }

解释:

初始化语句可以空着不写,表示循环之前不定义任何的控制变量。

条件判断语句可以空着不写,如果不写,默认表示true,循环一直进行。

条件控制语句可以空着不写,表示每次循环体执行完毕后,控制变量不做任何变化。

while格式:

while(true){ System.out.println("循环执行一直在打印内容"); }

解释:

​ 小括号里面就不能省略了,true一定要写出来,否则代码会报错。

do…while格式:

do{ System.out.println("循环执行一直在打印内容"); }while(true);

解释:

​ 小括号里面就不能省略了,true一定要写出来,否则代码会报错。

无限循环的注意事项:

最为常用的格式:while无限循环下面不能再写其他代码了,因为永远执行不到。 6.2条件控制语句 breakcontinue 6.2.1break

​ 不能单独存在的。可以用在switch和循环中,表示结束,跳出的意思。

代码示例:

//1.吃1~5号包子 for (int i = 1; i break;//结束整个循环。 } } 6.2.2continue

​ 不能单独存在的。只能存在于循环当中。

​ 表示:跳过本次循环,继续执行下次循环。

代码示例:

//1.吃1~5号包子 for (int i = 1; i //跳过本次循环(本次循环中,下面的代码就不执行了),继续执行下次循环。 continue; } System.out.println("在吃第" + i + "个包子"); }

Random跟Scanner一样,也是Java提前写好的类,我们不需要关心是如何实现的,只要直接使用就可以了。

7.数组

笔记小结:

定义:数组指的是一种容器,可以同来存储同种数据类型的多个值

定义方式:

格式一:

数据类型 [] 数组名; //例如 int [] array;

格式二:

数据类型 数组名 []; //例如 int array [];

注意:不同的数据类型对应不同的默认值

整数类型:0小数类型:0.0布尔类型:false字符类型:‘\u0000’引用类型:null

静态数组初始化:

格式一:

数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,元素4...}; //例如 double[] arr = new double[]{1.1,1.2,1.3};

格式二:

数据类型[] 数组名 = {元素1,元素2,元素3,元素4...}; //例如 int[] array = {1,2,3,4,5};

动态数组初始化:

格式:

数据类型[] 数组名 = new 数据类型[数组的长度]; //例如 double[] arr = new double[10];

数组动态初始化与数组的静态初始化的区别:

语法不同数组长度不同赋值时机不同注意:无论是何种数组,数组的最大长度为,数组的长度-1。例如:arr.length - 1

地址值:

含义:数组的地址值是指向数组对象的指针或引用

例如:

int[] arr = {1,2,3,4,5}; System.out.println(arr); //[I@6d03e736 /* [ :表示现在打印的是一个数组。 I:表示现在打印的数组是int类型的。 @:仅仅是一个间隔符号而已。 6d03e736:就是数组在内存中真正的地址值。(十六进制的) */

索引:

含义:用来标识它在数组中的位置

例如:

arr[0]、arr[1]、……

特点:

起始值为 0连续不间断逐个+1增长。

数组元素访问

含义:根据索引访问数组中的值格式:数组名[索引];

遍历

含义:依次取出元组中的元素

格式:

for(int i = 0; i 11,22,33}; double[] arr = new double[]{1.1,1.2,1.3}; /* 简化格式: 数据类型[] 数组名 = {元素1,元素2,元素3,元素4...}; */ int[] array = {1,2,3,4,5}; double[] array = {1.1,1.2,1.3};

细节:

数据类型:限定了数组以后能存什么类型的数据方括号:表示现在定义的是一个数组数组名:其实就是名字而已,方便以后使用,在起名字的时候遵循小驼峰命名法new:就是给数组在内存中开辟了一个空间大括号:表示数组里面的元素。元素也就是存入到数组中的数据。多个元素之间,一定要用逗号隔开

注意:

前面和后面的数据类型一定要保持一致数组一旦创建之后,长度不能发生变化 7.4数组的动态初始化 /* 格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; */ int[] agesArr = new int[3]; int[] scoresArr = new int[10]; 7.5地址值 int[] arr = {1,2,3,4,5}; System.out.println(arr);//[I@6d03e736 double[] arr2 = {1.1,2.2,3.3}; System.out.println(arr2);//[D@568db2f2

细节:

打印数组的时候,实际出现的是数组的地址值。数组的地址值:就表示数组在内存中的位置。

地址详细介绍

/* 以[I@6d03e736为例: [ :表示现在打印的是一个数组。 I:表示现在打印的数组是int类型的。 @:仅仅是一个间隔符号而已。 6d03e736:就是数组在内存中真正的地址值。(十六进制的) 但是,我们习惯性会把[I@6d03e736这个整体称之为数组的地址值 */ 7.6索引 7.6.1定义

​ 在Java中,索引也叫角标、下标。换句话说,就是数组容器中每一个小格子对应的编号。

7.6.2特点 索引一定是从0开始的。连续不间断。逐个+1增长。 7.7数组元素访问 7.7.1作用

获取数组中对应索引上的值

修改数组中对应索引上的值,一旦修改之后,原来的值就会被覆盖

7.7.2基本用例-数组访问演示 public class ArrDemo2 { /* 数组中元素访问的格式: 数组名[索引]; 作用: 1.获取指定索引上对应的元素 2.修改指定索引上对应的元素 */ public static void main(String[] args) { int[] arr = {1,2,3,4,5}; //需求1:获取arr数组中,3索引上的值 int number = arr[3]; System.out.println(number); System.out.println(arr[3]); //需求2:将arr数组中,3索引上的值修改为10 arr[3] = 10; System.out.println("修改之后为:" + arr[3]); } } 7.8数组的遍历 7.8.1遍历

​ 就是把数组里面所有的内容一个一个全部取出来。

7.8.2基本用例-数组遍历演示 /* 格式: 数组名.length */ for(int i = 0; i 1,2,3,4,5};

说明:

​ 手动指定数组的元素,系统会根据元素的个数,计算出数组的长度。

7.9.2动态初始化 int[] arr = new int[3];

说明:

​ 手动指定数组长度,由系统给出默认初始化值。

7.9.3应用场景 只明确元素个数,但是不明确具体的数据,推荐使用动态初始化。

说明:

// 使用数组来存储键盘录入的5个整数。 int[] arr = new int[5]; 已经明确了要操作的所有数据,推荐使用静态初始化。

说明:

// 将全班的学生成绩存入数组中,已知学生成绩为:66,77,88,99,100 int[] arr = {66,77,88,99,100} 7.9.4数组常见问题

索引越界

public class ArrDemo6 { public static void main(String[] args) { int[] arr = {1,2,3,4,5,5,5,5,5}; //用索引来访问数组中的元素 System.out.println(arr[1]); System.out.println(arr[10]);//ArrayIndexOutOfBoundsException } }

说明:针对于任意一个数组,索引的范围

最小索引:0最大索引: 数组的长度 - 1数组名.length - 1 8.代码块

笔记小结:

局部代码块:略

构造代码块:略

静态代码块(重点)

含义:被static修饰的代码块

基本用例:

/*格式: static{},需要通过static关键字修饰 */ static{ } // 当类加载时,此代码块就会被加载

特点:随着类的加载而加载,并且自动出发,只执行一次

8.1局部代码块 public class CodeBlockLearn { public static void main(String[] args) { { int a=10; System.out.println(a); } } }

说明:

应用场景:那么当超出了方括号,变量a也就不存在了,有着提前释放变量的作用 8.2构造代码块 卸载成员位置的代码块,可以把多个构造方法中重复的代码抽取出来执行时机:我们在创建本类对象的时候会先执行构造代码块再执行构造方法

说明:

​ 构造代码块优先于构造方法而执行的

8.3静态代码块(重点) /*格式: static{},需要通过static关键字修饰 */ public class MyClass { static { System.out.println("静态代码块执行了"); } public static void main(String[] args) { System.out.println("主方法执行了"); } }

说明:

执行时机:随着类的加载而加载,并且自动出发,只执行一次使用场景:在类加载时,做一些初始化的操作 9.关键字

笔记小结:见各模块

9.1this关键字

笔记小结:

定义:当我们在一个类中使用 this 时,它指的是该类的当前对象。

基础用例:

public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; //使用this关键字引用当前对象的成员变量name this.age = age; //使用this关键字引用当前对象的成员变量age } }

定义:在 Java 中,this 是一个关键字,表示当前对象。它可以用于访问当前对象的属性和方法。

基本用例

public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; //使用this关键字引用当前对象的成员变量name this.age = age; //使用this关键字引用当前对象的成员变量age } }

说明:

​ 当我们在一个类中使用 this 时,它指的是该类的当前对象。

9.2static关键字

笔记小结:

定义:static是一个关键字,用于修饰类的成员变量、成员方法和代码块,其作用是将这些成员变量、成员方法和代码块与类本身关联,而不是与类的实例对象关联

静态变量及其访问

含义:static修饰类的成员变量

定义:

/* 格式: 修饰符 static 数据类型 变量名 = 初始值;*/ public static String schoolName = "传智播客";

访问:

/* 格式: 类名.静态变量 */ System.out.println(Student.schoolName); // 传智播客

实例变量及其访问

含义:无static修饰类的成员变量

定义:

/* 格式: 修饰符 数据类型 变量名 = 初始值; */ public String schoolName = "传智播客";

访问:

/* 格式: 对象.方法名 */ Student stu = new Student(); System.out.println(stu.schoolName);

注意:

实例变量是属于每个对象,必须创建类的对象才可以访问静态变量不属于成员对象,属于类。该静态变量的加载随着类的加载而加载,优先于对象存在

静态方法及其访问

含义:static修饰类的成员方法

定义:

/* 格式: 修饰符 static 类型 方法名() */ public static void study(){ // 类方法或者静态方法。 System.out.println("我们都在黑马程序员学习"); }

访问:通过类名.方法名()

/* 格式: 类名.方法名() */ Student.study();

注意:实例方法是属于每个对象,必须创建类的对象才可以访问

实例方法及其访问

含义:无static修饰类的成员方法

定义:

/* 格式: 修饰符 类型 方法名()*/ public void study(){ // 类方法或者静态方法。 System.out.println("我们都在黑马程序员学习"); }

访问:需要new对象

/* 格式: 对象.方法名 */ Student stu = new Student(); System.out.println(stu.study());

内存图:

当使用了static关键字,会在堆内存中开辟一个名叫“静态存储位置”的内存空间静态方法不能访问非静态资源静态方法不能调用实例变量非静态资源可以访问所有注意,静态成员的生命周期与类的生命周期一样长 9.2.1概述

​ static是一个关键字,用于修饰类的成员变量、成员方法和代码块,其作用是将这些成员变量、成员方法和代码块与类本身关联,而不是与类的实例对象关联

9.2.1静态变量及其访问 9.2.1.1概述

​ 有static修饰成员变量,说明这个成员变量是属于类的,这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个,所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量。

9.2.1.2基本用例-static关键字使用 /* 格式: 修饰符 static 数据类型 变量名 = 初始值;*/ public class Student { public static String schoolName = "传智播客"; // 类变量或者静态成员变量 // ..... } 9.2.1.3访问 /*格式: 类名.静态变量 */ public static void main(String[] args){ System.out.println(Student.schoolName); // 传智播客 Student.schoolName = "黑马程序员"; System.out.println(Student.schoolName); // 黑马程序员 } 9.2.2实例变量及其访问 9.2.2.1概述

​ 无static修饰的成员变量属于每个对象的, 这个成员变量叫实例变量,之前我们写成员变量就是实例成员变量。

9.2.2.2基本用例-实例变量使用 public class Student { public String schoolName = "传智播客"; // 成员变量 // ..... } 9.2.2.3访问 /* 格式: 对象.实例成员变量 */ public static void main(String[] args) { Student stu = new Student(); System.out.println(stu.schoolName); }

细节:

​ 实例成员变量属于每个对象,必须创建类的对象才可以访问。

9.2.3静态方法及其访问 9.2.3.1概述

​ 有static修饰成员方法,说明这个成员方法是属于类的,这个成员方法称为类方法或者静态方法。 直接用 类名访问即可。因为类只有一个,所以静态方法在内存区域中也只存在一份。所有的对象都可以共享这个方法。

​ 与静态成员变量一样,静态方法也是直接通过类名.方法名称即可访问。

9.2.3.2基本用例 public class Student{ public static String schoolName = "传智播客"; // ..... public static void study(){ // 类方法或者静态方法。 System.out.println("我们都在黑马程序员学习"); } } 9.2.3.2访问 /* 格式: 类名.静态方法*/ public static void main(String[] args){ Student.study(); } 9.2.4实例方法及其访问 9.2.4.1概述

无static修饰的成员方法属于每个对象的,这个成员方法也叫做实例方法。

细节

​ 实例方法是属于每个对象,必须创建类的对象才可以访问

9.2.4.2基本用例-实例方法使用 /*格式: 对象.实例方法*/ public class Student { // 实例变量 private String name ; // 2.方法:行为 // 无 static修饰,实例方法。属于每个对象,必须创建对象调用 public void run(){ System.out.println("学生可以跑步"); } // 无 static修饰,实例方法 public void sleep(){ System.out.println("学生睡觉"); } public static void study(){ } } 9.2.4.3访问 public static void main(String[] args){ // 创建对象 Student stu = new Student ; stu.name = "徐干"; // Student.sleep();// 报错,必须用对象访问。 stu.sleep(); stu.run(); }

小结

1.当 static 修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。

2.无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。

3.static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。

4.无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用。

9.2.5Static内存图(重点)

静态方法

image-20230303143249383

说明:

若想让类中的某个成员变量被共享,可以将它变为static给修饰,这就是static的内存中的执行流程

补充:

方法入栈后会退出

注意事项:静态方法不能访问非静态

image-20230303151408269

说明:

若name是非static修饰,则不会出现在堆内存中的静态存储位置,因此静态方法不能访问非静态现在堆内存中并没有任何实例过的对象,因此静态方法不能调用实例变量

补充:

main方法中读取到Student.teacherName方法的Student时,会把Student.class字节码文件加载到方法区

image-20230303151626162

说明:

假如method方法中可以调用show方法,那么在栈内存中,这个???.show方法又是谁来进行调用,正常来说应该是由一个对象来进行调用,因此静态方法不能访问非静态

补充:

静态成员的生命周期与类的生命周期一样长,也就是说,当类被加载时,静态成员就被分配内存;当类被卸载时,静态成员所占用的内存也被释放。

9.2.6Static修饰成员变量和成员方法

image-20230303143546266

9.2.7工具类常用Static

帮助我们做一些事情的,但是不描述任何事物的类

1.有同学没听懂,我这里解释一下,上节课说到静态变量先于类创建

2.意思就是我先加载静态变量,再创建类,是按照这个步骤来的

3.那么 ,如果这个类只有方法,也就是工具类,我没必要创建这个类

4.因为我可以先于这个类直接调用方法,而只有静态方法可以优先被创建

9.2.8Static弊端 静态变量生命周期过长:静态变量在整个程序运行期间都存在,可能会导致占用大量的内存空间,影响程序的性能静态变量的并发访问问题:多个线程同时访问静态变量时可能会发生并发访问的问题,导致数据不一致或其他错误静态方法不能被子类覆盖:由于静态方法是属于类的,而非对象的,因此它们不能被子类覆盖,这限制了程序的灵活性静态方法调用非静态方法或变量时需要创建对象:由于静态方法属于类,无法直接访问非静态的方法或变量,因此需要通过创建对象来访问静态代码块无法处理异常:静态代码块中的语句无法处理异常,只能通过抛出异常来处理。

static静态方法执行–内存分析_静态方法运行时存在的_qingdao_java的博客-CSDN博客

9.3final关键字

笔记小结:

定义:final 是一个关键字,它可以用来修饰变量、方法和类,表示不可改变的、终态的。

修饰变量:

局部变量:表示它的值不能被改变,即该变量为常量。变量值不可被修改

final int a; a = 10;

成员变量:表示它的值不能被改变,即该变量为常量。变量只可在定义成员变量的时候立马赋值

final int num = 10;

变量明明规范:单个单词全部大写,多个单词间使用下划线隔开

修饰方法:表示该方法不能被子类重写(覆盖)

final public void show1() { System.out.println("Fu2 show1"); }

修饰类:表示该类被称为称为最终类(或不可扩展类),因为不能被其余类继承

final class Fu { }

细节:

final修饰的变量是基本类型:那么变量存储的数据值不能发生改变final修饰的变量是引用类型:那么变量存储的地址值不能发生改变,是其指向的对象的内容可以被修改 9.3.1概述

final 是一个关键字,它可以用来修饰变量、方法和类,表示不可改变的、终态的。

修饰变量: final 修饰的变量表示常量,一旦被赋值后,就不能再被改变。final 声明的变量必须在声明时或者在构造器中初始化,否则编译器会报错。声明 final 变量时,一般使用全大写字母和下划线来表示。 修饰方法: final 修饰的方法表示该方法不能被子类重写或覆盖。当一个类被声明为 final 时,其中所有的方法都会自动地成为 final,但是实例变量不会受到影响。 修饰类: final 修饰的类表示该类不能被继承。使用 final 修饰类可以保证该类的行为不会被改变,也可以提高代码的安全性和可靠性。 9.3.2修饰变量 9.3.2.1局部变量(重点) public class FinalDemo1 { public static void main(String[] args) { // 声明变量,使用final修饰 final int a; // 第一次赋值 a = 10; // 第二次赋值 a = 20; // 报错,不可重新赋值 // 声明变量,直接赋值,使用final修饰 final int b = 10; // 第二次赋值 b = 20; // 报错,不可重新赋值 } }

说明:

​ 基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。

9.3.2.2成员变量(重点)

成员变量涉及到初始化的问题,初始化方式有显示初始化和构造方法初始化,只能选择其中一个:

显示初始化(在定义成员变量的时候立马赋值)(常用); public class Student { final int num = 10; }

构造方法初始化(在构造方法中赋值一次)(不常用,了解即可)。

注意:每个构造方法中都要赋值一次!

public class Student { final int num = 10; final int num2; public Student() { this.num2 = 20; // this.num2 = 20; } public Student(String name) { this.num2 = 20; // this.num2 = 20; } }

说明:

​ 被final修饰的常量名称,一般都有书写规范,所有字母都大写。

9.3.3修饰方法 9.3.3.1概述

final修饰的方法,不能被重写

9.3.3.2基本用例-修饰方法演示 /* 格式: 修饰符 final 返回值类型 方法名(参数列表){ //方法体 } */ class Fu2 { final public void show1() { System.out.println("Fu2 show1"); } public void show2() { System.out.println("Fu2 show2"); } } class Zi2 extends Fu2 { // @Override // public void show1() { // System.out.println("Zi2 show1"); // } @Override public void show2() { System.out.println("Zi2 show2"); } } 9.3.4修饰类 9.3.4.1概述

final修饰的类,不能被继承

9.3.4.2基本用例-修饰类使用 /* 格式: final class 类名 { } */ final class Fu { } // class Zi extends Fu {} // 报错,不能继承final的类

说明:

​ 查询API发现像 public final class String 、public final class Math 、public final class Scanner 等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。

9.4private关键字

笔记小结:

概述:用于修饰类的成员变量和方法的修饰符作用:防止外部程序对对象的数据进行非法访问和操作 9.4.1概述

​ private是一个修饰符,可以用来修饰成员(成员变量,成员方法)

说明:

​ 被private修饰的成员,只能在本类进行访问,针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作

细节:

提供“get变量名()”方法,用于获取成员变量的值,方法用public修饰提供“set变量名(参数)”方法,用于设置成员变量的值,方法用public修饰 9.4.2基本用例-private关键字使用 /* 学生类 */ class Student { //成员变量 String name; private int age; //提供get/set方法 public void setAge(int a) { if(a120) { System.out.println("你给的年龄有误"); } else { age = a; } } public int getAge() { return age; } //成员方法 public void show() { System.out.println(name + "," + age); } } /* 学生测试类 */ public class StudentDemo { public static void main(String[] args) { //创建对象 Student s = new Student(); //给成员变量赋值 s.name = "林青霞"; s.setAge(30); //调用show方法 s.show(); } } 9.4.3案例-private的使用

需求:定义标准的学生类,要求name和age使用private修饰,并提供set和get方法以及便于显示数据的show方法,测试类中创建对象并使用,最终控制台输出 林青霞,30

示例代码:

/* 学生类 */ class Student { //成员变量 private String name; private int age; //get/set方法 public void setName(String n) { name = n; } public String getName() { return name; } public void setAge(int a) { age = a; } public int getAge() { return age; } public void show() { System.out.println(name + "," + age); } } /* 学生测试类 */ public class StudentDemo { public static void main(String[] args) { //创建对象 Student s = new Student(); //使用set方法给成员变量赋值 s.setName("林青霞"); s.setAge(30); s.show(); //使用get方法获取成员变量的值 System.out.println(s.getName() + "---" + s.getAge()); System.out.println(s.getName() + "," + s.getAge()); } } 9.5this关键字

笔记小结:

含义:this的本质就是所在方法调用者的地址值内存图: 方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量

this关键字内存原理(重点)

image-20230228093820021

image-20230228094218260

说明:

方法执行完成后会出栈

总结一句话:this的本质就是所在方法调用者的地址值

this修饰的变量用于指代成员变量,其主要作用是(区分局部变量和成员变量的重名问题)

方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,带this修饰的变量是成员变量方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量 public class Student { private String name; private int age; public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void show() { System.out.println(name + "," + age); } } 9.6super关键字

笔记小结:

含义:表示父类对象的引用,可以用来调用父类的构造方法、实例方法和实例变量

用法格式:

this.成员变量 -- 本类的 super.成员变量 -- 父类的 this.成员方法名() -- 本类的 super.成员方法名() -- 父类的 super(...) -- 调用父类的构造方法,根据参数匹配确认 this(...) -- 调用本类的其他构造方法,根据参数匹配确认

super用法示例:

super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现super(…)是根据参数去确定调用父类哪个构造方法的

内存图:

image-20230813112237941

细节:

子类的每个构造方法中均有默认的super( ),调用父类的空参构造。手动调用父类构造会覆盖默认的super( )

super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现

super( )和this( )是根据参数去确定调用父类哪个构造方法的

super( )可以调用父类构造方法初始化继承自父类的成员变量的数据

this( )可以调用本类中的其他构造方法

9.6.1概述

​ 在Java中super关键字,表示父类对象的引用,可以用来调用父类的构造方法、实例方法和实例变量

class Person { private String name; private int age; public Person() { System.out.println("父类无参"); } // getter/setter省略 } class Student extends Person { private double score; public Student() { //super(); // 调用父类无参构造方法,默认就存在,可以不写,必须再第一行 System.out.println("子类无参"); } public Student(double score) { //super(); // 调用父类无参构造方法,默认就存在,可以不写,必须再第一行 this.score = score; System.out.println("子类有参"); } // getter/setter省略 } public class Demo07 { public static void main(String[] args) { // 调用子类有参数构造方法 Student s2 = new Student(99.9); System.out.println(s2.getScore()); // 99.9 System.out.println(s2.getName()); // 输出 null System.out.println(s2.getAge()); // 输出 0 } }

说明:

​ 我们发现,子类有参数构造方法只是初始化了自己对象中的成员变量score,而父类中的成员变量name和age依然是没有数据的,怎么解决这个问题呢,我们可以借助与super(…)去调用父类构造方法,以便初始化继承自父类对象的name和age

9.6.3基本用例-super关键字使用 /* 格式: super.成员变量 -- 父类的 super.成员方法名() -- 父类的 */ class Person { private String name ="凤姐"; private int age = 20; public Person() { System.out.println("父类无参"); } public Person(String name , int age){ this.name = name ; this.age = age ; } // getter/setter省略 } class Student extends Person { private double score = 100; public Student() { //super(); // 调用父类无参构造方法,默认就存在,可以不写,必须再第一行 System.out.println("子类无参"); } public Student(String name , int age,double score) { super(name ,age);// 调用父类有参构造方法Person(String name , int age)初始化name和age this.score = score; System.out.println("子类有参"); } // getter/setter省略 } public class Demo07 { public static void main(String[] args) { // 调用子类有参数构造方法 Student s2 = new Student("张三",20,99); System.out.println(s2.getScore()); // 99 System.out.println(s2.getName()); // 输出 张三 System.out.println(s2.getAge()); // 输出 20 } }

注意:

子类的每个构造方法中均有默认的super(),调用父类的空参构造。手动调用父类构造会覆盖默认的super()。

super() 和 this() 都必须是在构造方法的第一行,所以不能同时出现。

super(…)是根据参数去确定调用父类哪个构造方法的。

9.6.4内存图

父类空间优先于子类对象产生

​ 在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造器调用时,一定先调用父类的构造方法。理解图解如下:

image-20230813112250239

9.6.5this( )基本用例

this(…)

默认是去找本类中的其他构造方法,根据参数来确定具体调用哪一个构造方法。为了借用其他构造方法的功能。 /* 格式: this.成员变量 -- 本类的 this.成员方法名() -- 本类的 */ package com.itheima._08this和super调用构造方法; /** * this(...): * 默认是去找本类中的其他构造方法,根据参数来确定具体调用哪一个构造方法。 * 为了借用其他构造方法的功能。 */ public class ThisDemo01 { public static void main(String[] args) { Student xuGan = new Student(); System.out.println(xuGan.getName()); // 输出:徐干 System.out.println(xuGan.getAge());// 输出:21 System.out.println(xuGan.getSex());// 输出: 男 } } class Student{ private String name ; private int age ; private char sex ; public Student() { // 很弱,我的兄弟很牛逼啊,我可以调用其他构造方法:Student(String name, int age, char sex) this("徐干",21,'男'); } public Student(String name, int age, char sex) { this.name = name ; this.age = age ; this.sex = sex ; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } }

说明:

​ this内存图,已在this关键字详细讲解

知识加油篇 1.Java内存模型

在Java中,执行一个HelloWorld方法的内存图

image-20230303093525909

说明:

​ 栈内存为方法提供使用、堆内存为对象提供使用、方法区为执行的class文件临时存储

补充:

参考资料:https://www.bilibili.com/video/BV17F411T7Ao/?p=107当执行main方法时,会生成StringDemo这个class文件 2.Idea快捷键 2.1查看接口实现类

说明:

Ctrl+Alt+B

选中一个方法,按键Ctrl+Alt+B即可查看实现此接口的实现类

image-20230321143750637

2.2图标小细节

Ctrl+F12可以查看当前类中的状态,例如成员方法,成员属性等等

image-20230424201934606

image-20230424202204121

C表示类,M表示方法,F表示常量或静态成员变量,➡️表示继承,⬆表示重写

3.int 和Integer 区别

​ 在Java中,int是一种原始数据类型(primitive data type),用于表示整数值。它是Java中最常用的数据类型之一,它的大小为4个字节(32位),可以表示介于-2,147,483,648和2,147,483,647之间的整数。

​ 而Integer是Java中的一个类(Class),它封装了一个基本类型的int的值。它允许将int值作为参数传递给需要一个对象的方法,也可以将int值转换为其他类型的值,例如字符串。

​ 因此,int和Integer的主要区别在于int是一个原始数据类型,而Integer是一个类,用于封装int值以便进行更多的操作。此外,int在Java中是一种基本数据类型,而Integer是一种引用数据类型,也就是说Integer实际上是一个指向对象的指针,而不是一个简单的数据值。

4.String 和Character 区别

​ String是一种对象,用于表示一个字符序列(即一组字符)。它是Java中的一个类,具有许多实用方法来操作和处理字符串,例如连接、替换、搜索和分割等。字符串常量可以使用双引号括起来,例如"hello"。

Character是Java中的char类型的包装类,它用于表示单个字符。每个Character对象都包含一个char类型的值。它也具有一些实用方法来操作和处理字符,例如将字符转换为大写或小写。字符常量可以使用单引号括起来,例如'A'。

​ 因此,String和Character的主要区别在于它们表示的数据类型不同。String用于表示一组字符,而Character用于表示单个字符。此外,String是一个类,而Character是一个简单的数据类型。在Java中,字符串是不可变的,因此不能在原始字符串上进行修改,而Character是可变的,因为它只表示一个字符。

5.基本数据类型和引用数据类型的区别

参考链接:(29条消息) 基本数据类型和引用数据类型的区别_Brandon懂你的博客-CSDN博客



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有