Java学习笔记

Java基础

JDK下载

http://www.oracle.com

安装路径统一,不要包含中文和空格

长期支持版本(LTS)

Java5.0 8.0 17.0

请添加图片描述

JDK安装
请添加图片描述

程序运行

程序编写(写代码)、编译(转换成机器语言)、运行(执行编译后的指令)

Java/jdk-17/bin/javac.exe编译

Java/jdk-17/bin/java.exe运行

编译.java文件生成.class文件(自解码文件)

javac Helloworld.java

运行.java文件

java Helloworld

环境变量

配置java.exe、javac.exe全局变量 bilibili

编译器

Notepad++

Java类型及应用

Java SE: Java语言标准版,用于桌面应用的开发。是其它两种版本的基础。

Java ME: Java语言小型版,用于嵌入式电子设备或者小型移动设备(已凉凉)

Java EE: Java语言企业版,用于Web网站开发(浏览器+服务器),领域No.1

桌面应用开发:各种税务管理软件、IDEA、Clion、Pycharm

企业级应用开发:微服务、spingcloud

移动应用开发:鸿蒙、android、医疗设备

科学计算:Matlab

大数据开发:hadoop

游戏开发:我的世界、MineCraft

Java特性

  1. 面向对象:根据要求创建对象
  2. 安全性
  3. 多线程:同时做多件事情
  4. 简单易用
  5. 开源:安装包+代码
  6. 跨平台:Windows、Mac、Linux(通过虚拟机实现跨平台)

高级语言类型

  1. 编译型:通过Arm/X86平台编译器整体翻译为机器指令执行(C)
  2. 解释型:通过Arm/X86平台编译器按行翻译(Python)
  3. 混合型:整体编译为字节码,通过平台执行器翻译,到Java提供的虚拟机执行机器指令(Java)

JRE

Java的运行工具,包括JVM、核心类库、开发工具

JDK

Java开发工具包,包括:

JVM虚拟机:java程序运行的地方

核心类库:java已经写好的东西,可以直接使用

开发工具:javac、java、jdb、jhat…

JDK>JRE>JVM

Java基础语法

注释

// 单行注释
/*多行注释*/
/**文档注释*/

关键字

关键字字母全部小写

class

用于创建/定义一个类,类是Java最基本的组成单元

public class Helloworld{
    // 类名要和文件名完全一致
}

字面量

数据在程序中的书写格式

整数类型:-88

小数类型:-5.21

字符串类型:“hello”、“我们”、" "(双引号)

字符类型:‘A’、‘我’(单引号,单个内容)

布尔类型:true、false

特殊字符:制表符(\t、\n、)、空类型(null)

变量

变量定义格式:

数据类型 变量名 = 数据值;
int a = 10;

变量使用:打印、计算、更新赋值

System.out.println(a);
int b = 20;
System.out.println(a + b);
a = 30;

变量注意事项

只能存一个值

不允许重复定义

一条语句可以定义多个变量

变量使用前一定要赋值

变量作用域

int c = 1, d = 2, e = 3;

数据存储

System.out.println(17); 	//十进制
System.out.println(017); 	//八进制
System.out.println(0b123); 	//语法错误
System.out.println(0x123); 	//十六进制

进制转化(x转十):系数*基数的权次幂 相加

101 = 1*2^2 + 0*2^1 + 1*2^0 = 4 + 0 + 1 = 5

进制转化(十转x):除基取余

除以基数,将余数倒着拼起来

RGB(0 ~ 255)(00 ~ FF)

数据类型

基本数据类型

整数、浮点数、字符、布尔

在这里插入图片描述

定义long类型变量,需要在数据值后面加一个L(大小也都可)作为后缀

定义folat类型变量,需要在数据值后面加一个F(大小也都可)作为后缀

取值范围:

double > float > long > int > short > byte

引用数据类型

标识符

给类、方法、变量等起的名字

命名规则

由数字、字母、下划线_和美元符$组成

不能以数字开头

不能是关键字

区分大小写

命名建议

见名知意

  1. 小驼峰命名法:方法、变量

单个单词小写name,多个单词首字母小写其它单词大写firstName

  1. 大驼峰命名法:类名

单个单词首字母大写Student,多个单词每个单词首字母大写GoodStudent

键盘录入

导包Scanner

import java.util.Scanner // 写在类定义上面

创建对象

Scanner sc = new Scanner(System.in);
// sc为变量,其它不变

接受数据

int i = sc.nextInt();
// i为变量,其它不变

IDEA

IntelliJ IDEA,用于Java语言开发的集成环境,把代码编写、编译、执行、调试等集成到一起的开发工具。

下载:https://www.jetbrains.com/idea/

IDEA项目结构:project、module、package、class

快捷输入:

psvm (public static void main(String[] args) )
sout (System.out.println();)
100.fori (for (int i; i<100; i++))
数组名.fori (遍历数组)
ctrl + alt + M 自动抽取方法

运算符

运算符:对字面量或者变量进行操作的符号

+ // 算术运算符

表达式:用运算符把字面量或者变量连接起来符合java语法的式子就可以称为表达式。不同运算符连接的表达式体现的是不同类型的表达式。

a+b // 算数表达式

算数运算符

+、-、*、/、%

// 代码中有小数参与计算,结果有可能不精确
1.1 + 1.1 = 2.2
1.1 + 1.01 = 2.110000000003
// 整数除法结果为整数,小数计算结果可能不精确
10 / 3 = 3
10.0 / 3 = 3.33333333333
// 取模(取余数),判断整数、奇偶、斗地主玩家
10 % 2 = 0
10 % 3 = 1
数值拆分

需求:键盘录入一个三位数,将其拆分为个位、十位、百位后,打印在控制台

输入整数:123

个位:数值 % 10

十位:数值 /10 % 10

百位:数值 /100 % 10

package test;
import java.util.scanner;

public class Test1 {
    public static void main(string[] args){
        //健盘录入一个三位数,获取其中的个位,十位,百位
		//1.键盘录入
		Scanner sc = new Scanner(System.in);
		System.out.println("诸输入一个三位数");
		int number = sc.nextInt();
		//2.获取个位,十位,百位
		int ge = number % 10;
        int shi = number / 10 % 10;
        int bai = number / 100 % 10;
        System.out.println(ge);
        System.out.println(shi);
        System.out.println(bai);
类型转换

隐式转换(自动类型提升):取值范围小 → 大

强制转换:取值范围大 → 小

byte < short < int < long < float < double

隐式转换的两种提升规则

  1. 取值范围小的,和取值范围大的进行运算,小的会先提升为大的,再进行运算(不同类型不能直接计算)

  2. byte short char 三种类型的数据在运算的时候,都会直接先提升为int,然后再进行运算

byte a = 10;
byte b = 20;
c = a + b  // 此时c为int

强制转换

如果把一个取值范围大的数值,赋值给取值范围小的变量,是不允许直接赋值的。如果一定要这么做就需要加入强制转换

格式:

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

byte b1 = 10;   // 0000 1010
byte b2 = 20;   // 0001 0100
byte r = (byte) (b1 + b2)
    
30

int a = 200;
b = (byte) a
    
-56  // 转换数据过大,结果错误
// a 0000 0000 0000 0000 0000 0000 1100 1000
// b 1100 1000
字符串+

当“+”操作中出现字符串时,这个“+”是字符串连接符,而不是算术运算符了会将前后的数据进行拼接,并产生一个新的字符串。

“123” + 123 → “123723”

“abc” + true → “abctrue”

连续进行"+"操作时,从左到右逐个执行。

1 + 99 + “年黑马” → "100年黑马”

字符+

字符+字符、字符+数字时,会把字符通过ASCII码(American Standard Code for Information Interchange)表查询到对应的数字再进行计算

A:65 a:97

1 + 'a'98

自增自减运算符

++和–既可以放在变量的前边,也可以放在变量的后边,单独写一行的结果一样

int a = 10;
++a;   // 11
a++;   // 12
a--;   // 11
--a;   // 10

参与计算时,放前后的计算结果不同

// 先用后加
int a = 10;
int b = a++;  // b = 10, a = 11
// 先加后用
int a = 10;
int b = ++a; // b = 11, a = 11

赋值运算符

在这里插入图片描述

+=、-=、*=、/=、%= 隐藏了一个强制类型转换

short s = 1;
s += 1;
// 等同于 s = (short) (s + 1);

关系运算符

关系运算符/比较运算符

在这里插入图片描述

关系运算符的结果都是boolean类型,要么是true,要么是false。千万不要把“==”误写成“=”

逻辑运算符

在这里插入图片描述

短路逻辑运算符

在这里插入图片描述

A && B // A=True才判断B,A=False时B不用判断
A || B // A=True直接为True,A=False时才判断B

三元运算符

格式:关系表达式? 表达式1: 表达式2

// 获取两个数的较大值
int max = a > b ? c : d

计算规则:

首先计算关系表达式的值

如果值为true,表达式1的值就是运算结果

如果值为false,表达式2的值就是运算结果

运算符优先级

小括号优先于所有

在这里插入图片描述

原码、反码、补码

原码:十进制数据的二进制表现形式,最左边是符号位,0为正,1为负

56 → 0011 1000

8 bit = 1字节

一个字节最大值为 0111 1111 → +127

一个字节最小值为 1111 1111 → -127

1个字节范围为-128 ~ +127

但是如果是负数计算,结果就出错,实际运算的结果,跟我们预期的结果是相反的。

反码:正数的补码反码是其本身,负数的反码是符号位保持不变,其余位取反

正数的反码不变,负数的反码在原码的基础上符号位不变
数值取反
,0变1,1变0。

在这里插入图片描述

补码:正数的补码是其本身,负数的补码是在其反码的基础上+1

为了解决负数计算时跨0的问题而出现的。

-128没有原码和反码,补码为1000 0000
在这里插入图片描述

流程控制语句

顺序结构

顺序结构语句是Java程序默认的执行流程,按照代码的先后顺序,从上到下依次执行

分支结构

if语句

if语句1

if (关系表达式) {
	语句体;
}
// 如果只有一句代码可以不写大括号(一行不一定算一句),一般建议加大括号
if (关系表达式)
    语句体;

if语句2

if (关系表达式) {
	语句体;
} else {
    语句体;
}

if语句3

if (关系表达式1) {
	语句体1} else if (关系表达式2) {
    语句体2;
}
	...
} else {
	语句体 n;
}
switch语句
switch (表达式) {
    case1:
        语句体1;
        break;
    case2:
        语句体2;
        break;
    ...
    default:
        语句体n;
        break;
}

表达式取值为byte、short、int、char,JDK5以后可以是枚举,JDK7以后可以是String

case后面的值只能是字面量,不能是变量,且不允许重复

default位置不一定写最下面,习惯写最下面,省略不会有语法问题。

case穿透:语句体没有写break,会继续执行下一个case语句,直到break或大括号

// JDK12的switch新特性
int num = 1;
switch (num){
        case 1-> {
            system.out.println("yi")
        }
        case 2-> {
            system.out.println("er")
        }
        default -> {
            system.out.println("没有该选项")
        }
}
// 单语句可省略括号
int num = 1;
switch (num){
        case 1-> system.out.println("yi")
        case 2-> system.out.println("er")
        default -> system.out.println("没有该选项")
}

循环结构

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

相同点:运行规则都是一样的

for 和 while 的区别:

for循环中,控制循环的变量,因为归属for循环的语法结构中,在for循环结束后,就不能再次被访问到了

while循环中,控制循环的变量,对于while循环来说不归属其语法结构中,在while循环结束后,该变量还可以继续使用(书上错不严谨的说法)

初始化语句
for ( ; 条件判断语句 ; 条件控制语句){
    循环体语句;
}
  1. for循环中:知道循环次数或者循环的范围

  2. while循环:不知道循环的次数和范围,只知道循环的结束条件

do…while循环
初始化语句;
do {
    循环体语句;
    条件控制语句;
} while(条件判断语句);
无限循环
// for无限循环
for (;;) {
    System.out.println("hello");
}

// while无限循环
while (true){
    System.out.println("hello");
}

// do...while无限循环
do {
    System.out.println("hello");
} while(true);

无限循环下面不写代码了,代码执行不到

跳转控制语句
// 跳过本次循环
for (int i=1; i<=5; i++){
    if(i==3){
        continue;
    }
    System.out.println(i);
}

// 结束整个循环
for (int i=1; i<=5; i++){
    if(i==3){
        break;
    }
    System.out.println(i);
}

continue:跳过本次循环,继续执行下次循环。
break:结束整个循环。

获取随机数
import java.util.Random
Random r = new Random();
int number = r.nextInt(bound: 100); // [0, 99]

数组

可以用来存储同种数据类型的多个值

数组容器在存储数据的时候,需要结合隐式转换考虑。

例如:int类型的数组容器(boolean× byte√ short√ int√ double×)

double类型的数组容器(byte√ short√ int√ long√ double√)

建议:容器的类型,和存储的数据类型保持一致

数组的定义

// 格式一:数据类型[] 数组名
int [] array

// 格式二:数据类型 数组名[]
int array[]

数组初始化

初始化就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程

// 数据类型[] 数组名=new 数据类型[]{元素1,元素2,元素3...};
int[] array = new int[]{11, 22, 33};
double[] array2 = new double[]{11.1, 22.2, 33.3};

// 简写格式
int[] array = {11, 22, 33};
double[] array2 = {11.1, 22.2, 33.3};

初始化后数组长度不会再发生变化

数组地址值

数组的地址值表示数组在内存中的位置

int[] arr = {1,2,3,4,5};
System.out.println(arr); // [I@6d03e736
// [表示当前是一个数组
// D表示当前数组内元素都是double类型,I为int
// @表示一个间隔符号,固定格式
// 6d03e736才是数组真正地址值,十六进制
// 平时习惯把整体叫做地址值

索引

也叫做下标,角标。从0开始,逐个+1增长,连续不间断

// 获取数组元素及赋值
int[] arr = {1, 2, 3, 4, 5};
int num = arr[0];
// 存储和覆盖
arr[0] = 100;

遍历

将数组中所有的内容取出来,取出来之后可以(打印,求和,判断…)

遍历指的是取出数据的过程,不要局限的理解为遍历就是打印!

for (int i=0; i<arr.length; i++){
    System.out.println(arr[i])
}
// IEDA快捷语句 数组名.fori

数组动态初始化

初始化时只指定数组长度,由系统为数组分配初始值。

数据类型[] 数组名 = new 数据类型[数组长度];
int[] arr = new int[3];

默认初始化值

int 0

小数 0.0

字符 ‘/u0000’ (空格)

布尔 false

引用 null

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

(只明确元素个数,不明确具体数值,推荐使用动态初始化)

静态初始化:手动指定数组元素,系统会根据元素个数,计算出数组的长度,

(需求中已经明确了要操作的具体数据,直接静态初始化即可。)

数组内存图

Java内存分配

  1. :方法运行时使用的内存,比如main方法运行,进入方法栈中执行

  2. :存储对象或者数组,new来创建的,都存储在堆内存

  3. 方法区:存储可以运行的class文件

  4. 本地方法栈:JVM在使用操作系统功能的时候使用,和我们开发无关

  5. 寄存器:给CPU使用,和我们开发无关

  6. 只要是new出来的一定是在堆里面开辟了一个小空间

  7. 如果new了多次,那么在堆里面有多个小空间,每个小空间中都有各自的数据

// 两个数组指向同一个空间的内存图
int[] arr1 = {11, 22};
int[] arr2 = arr1;

当两个数组指向同一个小空间时,其中一个数组对小空间中的值发生了改变,那么其他数组再次访问的时候都是修改之后的结果了。

常见问题

索引越界异常

常见操作

求最值

int[] arr = {1, 33, 5};
int max = arr[0]; // max的初始化值一定是数组中的值
// 从1开始循环,提高效率(0是跟自己比)
for (int i=1; i<arr.length; i++){
    if (arr[i] > max){
        max = arr[i];
    }
}

求和

// 生成1~100的随机数保存到数值,并求和
// 定义随机数
int[] arr = new int[10];
Random r = new Random();

// 将随机数保存到数组
for (int i=0; i<arr.length; i++){
    int number = r.nextInt(100) + 1;
    arr[i] = number;
}

// 求数组中的元素和
int sum = 0;
for (int i=0; i<arr.length; i++){
    sum = sum + arr[i];
}

交换数据

int[] arr = {1, 2, 3, 4, 5};

for (int i=0, j= arr.length -1; i<j; i++, j--){
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

打乱数据

int[] arr = {1, 2, 3, 4, 5};
Random r = new Random();
for (int i=0; i<arr.length; i++){
    // 生成一个0 ~ arr.length-1的随机索引
    int randomIndex = r.nextInt(arr.length);
    int temp = arr[i];
    arr[i] = arr[randomIndex];
    arr[randomIndex] = temp;
}


方法

方法(method)是程序中最小的执行单元。

重复的代码、具有独立功能的代码可以抽取到方法中。

可以提高代码的复用性、可以提高代码的可维护性

方法的格式

public class demo{
    public static void main(String[] args){
        // 调用
		方法名();
    }
}
// 定义
public static void 方法名(){
    方法体(就是打包起来的代码);
}
带参数的方法
public class demo{
    public static void main(String[] args){
        // 带参数方法的调用(个数、类型对应)
        method(10, 20); // 实参
    }
}
// 带参数方法定义
// 形参
public static void method(int numl, int num2){
    int result = num1 + num2;
    System.out.println(result);
}
带返回值的方法(完整定义)

方法的返回值其实就是方法运行的最终结果。

调用处拿到方法的结果之后,才能根据结果进行下一步操作

public static 返回值类型 方法名(参数){
    方法体;
    return 返回值;
}

调用

// 直接调用
方法名(实参);
// 赋值调用
整数类型 变量名 = 方法名(实参);
// 输出调用
System.out.peintln(方法名(实参));

形参和实参

形参:全称形式参数,是指方法定义中的参数

实参:全称实际参数,方法调用中的参数

方法定义:

  1. 我要干什么(方法体)

  2. 干这件事需要什么才能完成(形参)

注意事项

  1. 方法不调用就不执行

  2. 方法与方法是平级关系,不能互相嵌套定义

  3. 方法定义在main前后都行,一般放后面,不能放在main里面

  4. 方法编写顺序与执行顺序无关

  5. 方法的返回值类型为void,表示该方法没有返回值,没有返回值的方法可以省略return语句不写。如果要编写return,后面不能跟具体的数据。

public static viod 方法名(参数){
    方法体;
    return;
}
  1. return语句下面,不能编写代码,因为永远执行不到,属于无效的代码

return关键字

  1. 方法没有返回值:可以省略不写。如果书写,表示结束方法
  2. 方法有返回值:必须要写。表示结束方法和返回结果

方法的重载

在同一个类中,定义了多个同名的方法,这些同名的方法具有同种的功能。

每个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系

简单记:同一个类中,方法名相同,参数不同(包括数目和类型)的方法。与返回位无关。

Java虚拟机会通过参数的不同来区分同名的方法

return break关键字的区别

return:其实跟循环没有什么关系。跟方法有关的,表示1结束方法2返结果

如果方法执行到了return。那么整个方法全部结束。里面的循环也会随之结束了

break关键字:其实跟方法没有什么关系。结束循环或者switch的。

方法的内存

  1. 方法调用的基本内存原理

栈:先进后出,根据程序运行顺序进出栈

基本数据类型:数据值是存储在自己的空间中(特点:赋值给其他的变量,也是赋的真实的值)

int a = 10;
int b = a;

引用数据类型:数据值是存储在其它空间中,自己空间中存储的是地址值(特点:赋值给其它变量,赋的是地址)

int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
  1. 方法传递基本数据类型的内存原理

栈内存

传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值

  1. 方法传递引用数据类型的内存原理

引用数据类型中,变量存储的是地址值

引用:使用了其它空间中的数据

传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值

IDEA快捷键

ctrl + alt + M 自动抽取方法

shift + F6 选中相同变量

ctrl + alt + t 加上while循环

二维数组

数组中存数组,分组管理数据

静态初始化
数据类型[][] 数组名 = new 数组类型[][]{{元素1, 元素2}, {元素1, 元素2}};
// 简写
int[][] arr = {{11, 22}, {33, 44}}; // 阿里巴巴编码规范
int arr[][] = {{11, 22}, {33, 44}};
动态初始化
数据类型[][] 数组名 = new 数组类型[m][n]// m表示这个二维数组,可以存放多少个一维数组
// n表示每一个一维数组,可以存放多少个元素

二维在这里插入图片描述
数组内存图

特殊情况
// 1. 不定义一维数组长度
int[][] arr = new int[2][];
int[] arr1 = {11, 22};
int[] arr2 = {44, 55, 66};
arr[0] = arr1;
arr[1] = arr2;

// 2. 一维数组被覆盖和替换
int[][] arr = new int[2][3];
int[] arr1 = {11, 22};
int[] arr2 = {44, 55, 66};
arr[0] = arr1;
arr[1] = arr2;

面向对象

面向对象编程:拿东西过来解决问题

  1. 学习获取已有对象并使用

  2. 自己设计对象并使用(面向对象的语法)

设计对象并使用

类和对象

类(设计图):是对象共同特征的描述;

对象:是真实存在的具体东西。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值