Java 基础语法

1、标识符和关键字

标识符

类名、变量名以及方法名都被称为标识符。

  • 以字母(a - z / A - Z)/ 下划线(_)/ 美元符($)开头,后跟字母 / 下划线 / 美元符 / 数字
  • 不能以数字开头,不能使用关键字命名
  • 大小写敏感

关键字

java 关键字学习:https://baike.baidu.com/item/java关键字/5808816

在这里插入图片描述

注意:Java 的 null 不是关键字,类似于 true 和 false,它是一个字面常量,不允许作为标识符使用。

2、数据类型

2.1、类型介绍

Java是强类型语言——变量的使用要严格符合规定,所有的变量都要先定义后才能使用。

  • 基本数据类型(四类八种)
    • 整数:byte、short、int(默认)、long
    • 浮点数:float、double(默认)
    • 布尔:boolean
    • 字符(单个):char
  • 引用数据类型
    • 接口
    • 数组
      在这里插入图片描述

拓展

public static void main(String[] args) {
    // 整数扩展 进制
    int num1 = 0b10; // 二进制 0b
    int num2 = 010;  // 八进制 0
    int num3 = 0x10; // 十六进制 0x
    int num4 = 10;  // 默认是十进制

    System.out.println(num1); // 2
    System.out.println(num2); // 8
    System.out.println(num3); // 16
    System.out.println(num4); // 10

    System.out.println("==================================");
    // ===================================================
    // 浮点数扩展 精度丢失 离散 大约 接近但不等于
    // 最好避免使用浮点数进行比较运算
    // 金融使用 BigDecimal 数学工具类
    // ===================================================
    float f1 = 0.1F;
    double d1 = 1.0/10;
    System.out.println(f1 == d1); // false
    System.out.println(f1); // 0.1
    System.out.println(d1); // 0.1


    float f2 = 1123123123123123F;
    float f3 = f2 + 1;
    System.out.println(f2 == f3); // true

    System.out.println("==================================");
    // ===================================================
    // 字符扩展 Unicode 编码 2Byte 0-65536 0000-FFFF 字符本质上是数字
    // ===================================================
    char c1 = 'a';
    char c2 = '忠';
    char c3 = 0x0061;
    char c4 = '\u0061';
    System.out.println(c1); // a
    System.out.println((int)c1); // 97
    System.out.println(c2); // 忠
    System.out.println((int)c2); // 24544
    System.out.println(c3); // a
    System.out.println(c4); // a

    System.out.println("==================================");
    // ===================================================
    // 字符串 String 不是关键字
    // ===================================================
    String str1 = new String("Hello World");
    String str2 = new String("Hello World");

    System.out.println(str1 == str2); // false

    String str3 = "Hello World";
    String str4 = "Hello World";

    System.out.println(str3 == str4); // true
}

2.2、类型转换

由于Java是强类型语言,在进行一些运算时需要用到类型转换

类型转换:同一类型直接进行运算,不同类型首先转换成同一类型再进行运算,转换的规则是根据表示的数据范围从小向大的进行转换。

在这里插入图片描述

注:float 和 int 虽同为 4 字节,但 float 表示的范围比 int 要大

  • 强制类型转换(范围由低到高):(类型)变量名
// 计算机中数字采用补码存储,需要转换成原码方便我们查看
// 00000000 00000000 00000000 10000001 129 (原码表示)
// 00000000 00000000 00000000 10000001 129 (补码表示)
int i = 129;
// 强制类型转换 (类型)变量名,截取后八位 1,0000001 -1 (补码表示)
byte b = (byte) i;
// -127 = 1 + 2 + 4 + 8 + 16 + 32 + 64  1,1111111 -127 (原码表示)
System.out.println(b);
  • 自动类型转换(范围由高到低)
short s =  32767; // 32767 默认是 int 类型,自动转为 short 类型
char c1 = 61;     // int --> char
char c2 = 0x0061;
System.out.println(c1); // =
System.out.println(c2); // a

注:

  1. 不能对布尔值进行类型转换
  2. 范围大强制转换成范围小时有可能会发生溢出或者精度丢失
  3. 不能把对象类型转换成不相干的类型
int money1 = 1000000000; // 十亿
// JDK1.7特性,数字下面加下划线,方便区分,下划线不会被输出
int money2 = 10_0000_0000;
System.out.println(money1); // 1000000000
System.out.println(money2); // 1000000000

System.out.println("===========================");
int year = 20;
int res = year * money1;
System.out.println(res); // -1474836480 溢出

long res1 = year * money1;
// -1474836480 溢出 year money1 默认是int,转换之前就存在问题
System.out.println(res1);

long res2 = ((long)year) * money1;
System.out.println(res2); // 20000000000

long res3 = (long)year * money1;
System.out.println(res3); // 20000000000

long res4 = (long)(year * money1);
System.out.println(res4); // -1474836480

3、变量

变量

  • Java 变量是程序最基本的存储单元,要素包括变量名、变量类型和作用域。
  • 每个变量都有类型,可以是基本类型也可以是引用类型。
  • 变量名必须是合法的标识符。
  • 变量的声明是一条完整的语句,必须以分号结尾。
type varName [=value][{,varName[=value]}];
数据类型 变量名 = 值; // 可以用逗号分隔开,来声明同一类型的变量
  • 变量的使用必须先经过初始化才能使用。

变量的作用域

public class Demo02 {
   static int var1 = 1; // 类变量
   String str = "Hello,World"; // 实例变量
   
   public void method(){
      int var2 = 2; // 局部变量
   }
}

类变量、实例变量不手动初始化,会自动赋予该类型的默认值

局部变量必须手动初始化才能使用

  • byte、short、int、long 默认值为 0
  • float double默认值为 0.0;char 类型默认值一个空白字符
  • 引用类型默认值为 null

常量

  • 初始化以后不能在运行过程中改变的值,是一种特殊的变量
  • 使用修饰符 final 修饰
  • 使用过程中只能赋值一次,无法二次赋值
  • 常量名推荐使用大写字母表示
final 数据类型 常量名 = 值;
final double PI = 3.14;

4、运算符

java语言支持的运算符:

基本运算符 符号
算数运算符 +、-、*、/、%、++、- -
赋值运算符 =
关系运算符 >、<、>=、<=、==、!=、instanceof
逻辑运算符 &&、||、!
位运算符 &、`
条件运算符 ? :
扩展运算符 +=、-=、*=、/=

<<:有符号左移

>>:有符号右移

>>>:无符号右移

自增、自减

int a = 3;
int b = a++;
int c = ++a;

System.out.println(a); // 5
System.out.println(b); // 3
System.out.println(c); // 5

逻辑与 && :短路

int i = 1;
System.out.println(false&& (++i > 0)); // false
System.out.println(i); // 1

有符号左移 <<

System.out.println(1 << 3);// 00001 --> 01000 8

字符串拼接

int a = 10;
int b = 20;

System.out.println("" + a + b); // 1020
System.out.println(a + b + ""); // 30
System.out.println(a + "" + b); // 1020

5、包机制

  • 区别类名的命名空间
  • 一般利用公司域名倒置作为包名
  • 包语句的语法格式为:
package pk1[.pk2 [ .pk3... ] ];
  • 使用某一个包下的类时,用关键字 import 进行导包操作;
import package1[ .package2 ... ].(classname|*);

6、JavaDoc 文档注释

javadoc 命令是用来生成自己的 API 文档的

格式:

javadoc 参数 java文件
例如:javadoc -encoding UTF-8 -charset UTF-8 ClassName.java

参数信息:

  • @author:作者名
  • @version:版本号
  • @since:指明需要最早使用的 JDK 版本
  • @param:参数名
  • @return:返回值情况
  • @throws:异常抛出情况

7、Scanner 类

// 创建一个扫描器对象,用于接收用户键盘的输入
Scanner scanner = new Scanner(System.in);
// next():接收到第一个有效字符之后,以空格或回车为结束标识
// String str = scanner.next();
// nextLine():完整的输出该行的所有内容,以回车为结束标识
String str = scanner.nextLine();
System.out.println(str);

// 关闭扫描器对象 释放资源
scanner.close();

练习

/*
   输入多个数字,并求其总和与平均数
   每输入一个数字用回车确认, 通过输入非数字来结束输入并输出执行结果
 */

Scanner scanner = new Scanner(System.in);
double sum = 0;
int cnt = 0;

System.out.print("请输入数字: ");
while (scanner.hasNextDouble()) {
    System.out.print("请输入数字: ");
    double x = scanner.nextDouble();
    sum += x;
    if (x != 0) {
        cnt++;
    }
};
System.out.println("总和:" + sum);
System.out.println("平均数:" + (sum / cnt));

scanner.close();

8、流程控制

8.1、if 选择结构

语法格式:

if(条件1){}
else if(条件2){}
 ...
else if(条件n){}
else {}

8.2、switch(匹配)选择结构

语法格式:

switch(表达式){
    case value1:
        // 语句
        break; // 可选 不加会导致 case 穿透:下面的 case 语句都会执行
    case value2:
        // 语句
        break; // 可选
    ...
    case valuen:
        // 语句
        break; // 可选
    default:  // 可选
        // 语句
}

注:

  • switch 表达式中的类型只能是 byte、short、int、char、String(jdk1.7支持)、枚举

  • 也可以是基本类型的包装类:Byte、Short、Integer、Character

  • case 标签的值必须为字符串常量或者字面量,不能是一个变量!

在这里插入图片描述

break、continue、return 的区别

  • break:用在循环体语句 or switch 语句中,用于强制退出循环,不执行循环中剩余的语句
  • continue:用在循环语句体中,跳过此次循环,接着进行下一次是否执行循环的判定
  • return:结束方法,返回一个结果(可以是空,也可以是其他,看返回值类型)

8.3、while 循环

语法格式:

while(循环条件——布尔表达式){
    // 循环体
}

例:1+2+3+……+100 = ?

int sum = 0;
int i = 0;
while (i < 100){
   i++;
   sum += i;
}
System.out.println(sum);

8.4、do … while 循环

语法格式:

do{
    // 循环体
}while(循环条件——布尔表达式);

while 和 do … while 的区别

  • do … while 先执行再判断,while 先判断再执行
  • do … while 循环至少执行一次,while 循环不满足条件一次也不执行

8.5、for 循环(重要)

for 循环一般用在循环次数确定情况下。

语法格式:

for(初始化表达式; 循环条件; 操作表达式){
    // 循环体
}

例 1:分别计算0-100之间的奇数和与偶数和

// 偶数和
int evenSum = 0;
// 奇数和
int oddSum = 0;
// 计算0-100之间的奇数和和偶数和
for (int i = 0; i <= 100; i++) {
    // 偶数
    if (i % 2 == 0) {
        evenSum += i;
    }
    // 奇数
    if (i % 2 != 0) {
        oddSum += i;
    }
}

System.out.println("偶数和为:" + evenSum);
System.out.println("奇数和为:" + oddSum);

例 2:1-1000能被5整除的数,每行输出三个

// 1-1000能被5整除的数,每行输出三个
int cnt = 0;
for (int i = 1; i <= 1000; i++) {
   if (i % 5 == 0) {
      cnt = cnt + 1;
      if (cnt != 3) {
         System.out.print(i + "\t");
      } else {
         System.out.print(i);
      }
   }
   if (cnt == 3) {
      System.out.println();
      cnt = 0;
   }

}

例 3:九九乘法表

// 九九乘法表
for (int i = 1; i <= 9; i++) {
    for (int j = 1; j <= i; j++) {
        System.out.print(j + " * " + i + " = " + (i * j) + "\t");
    }
    System.out.println();
}

例 4:

1)打印正三角形:找规律 根据打印的行数 每一行空格数目、星号数目

/*
打印正三角形
    *
   ***
  *****
 *******
*********
 */
int line = 5; // 打印三角形的行数
for (int i = 1; i <= line; i++) {
    for (int j = 1; j <= line - i; j++) { // 控制打印空格的数目
        System.out.print(" ");
    }
    for (int j = 1; j <= 2 * i - 1; j++) { // 控制打印星号的数目
        System.out.print("*");
    }
    System.out.println();
}

2)打印倒三角形

/*
打印倒三角形
*********
 *******
  *****
   ***
    *
 */
int line = 5;
for (int i = 1; i <= line; i++) {
   for (int j = 1; j < i; j++) { // 控制打印空格的数目
      System.out.print(" ");
   }
   for (int j = 1; j <= 2*(line-i)+1 ; j++) { // 控制打印星号的数目
      System.out.print("*");
   }
   System.out.println();
   
}

8.6、foreach 循环

java 5 引入,带有迭代器的 for 循环 —— foreach,主要用于解决数组或集合的遍历问题

语法格式:

for(变量类型 临时变量名 : 数组 | 集合变量名){
    // 语句块
}

例:

// 定义一个数组
int[] arrs = {10, 20, 30, 40, 50};
// for循环遍历数组元素
for (int i = 0; i < arrs.length; i++) {
   System.out.println(arrs[i]);
}

System.out.println("======================");
// 增强for循环遍历数组元素
for (int x : arrs) {
   System.out.println(x);
}

注:

如果想要改变数组或集合里的值,不要使用 foreach 循环。

示例:

// foreach 循环,迭代器 无法更改数组里的元素的值
int[] nums = {1, 3, 5, 6, 7, 8};
for (int num : nums) {
    num = 10;
    System.out.println(num);
}
System.out.println(Arrays.toString(nums));

结果:

10
10
10
10
10
10
[1, 3, 5, 6, 7, 8]

9、方法

9.1、方法的定义

java 中的方法也就是函数,完成指定功能的程序的集合

一个方法包括两大部分:方法头和方法体

语法格式:

修饰符 返回值类型 方法名称(参数类型 参数名){  // 方法头
    // 方法体
    return 返回值; // 返回值类是 void 可以不加return语句
}

9.2、方法的重载

重载就是在一个类中,有相同的方法名,但形参列表不同

重载规则:

  • 方法名相同
  • 形参列表不同(个数、类型、排列顺序)
  • 方法的返回值类型可以相同也可以不同
  • 仅返回值类型不同无法构成方法的重载

9.3、可变参数

java 1.5 开始提供可变参数

使用:在指定参数类型后面添加一个省略号(英文) …

修饰符 返回值类型 方法名称(参数类型... 参数名){  
    // 方法体
    return 返回值; 
}

注意:一个方法中只能有一个可变参数,如果有普通参数的话,必须在所有普通参数之后

9.4、静态方法和非静态方法

静态方法:被修饰符 static 修饰的

非静态方法:没有被 static 修饰的

  • 遵循一个原则:被static修饰的内容会跟随类的加载而加载
  • 静态化的内容可以不用实例化,通过类名.XX()直接调用
  • 两个静态方法之间也可以互相调用
  • 非静态方法可以调用静态方法,但静态方法无法调用非静态方法
  • static 修饰的方法不能使用 this 引用
public static void a() {
    // 报错,非静态的内容无法出现在静态内容的上下文环境中
   b();
}

public void b() {

}

9.5、值传递和引用传递

先给出结论:java 是值传递

对于基本类型来说是值传递,对于引用类型来说看似是引用传递,本质上还是值传递

基本类型

对于基本类型,函数调用时传递的是当前变量值的一个副本,对副本进行操作不会影响源变量的值

举例:交换两个数

代码:

public static void main(String[] args) {
   int a = 10;
   int b = 20;
   swap(a, b);
   System.out.println("a = " + a + ", b = " + b); 
   // a = 10, b = 20
}

static void swap(int x, int y) {
   int tmp = x;
   x = y;
   y = tmp;
}

内存简单分析:

在这里插入图片描述

swap 方法结束后,swap 方法中的临时变量销毁,并不会改变原来 a 和 b 的值。

引用类型(重点关注)

对于引用类型,函数调用时传递的是当前引用的一个副本

在这里插入图片描述

10、数组

一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。

即使把某个数组元素的数据清空,但它所占的空间依然被保留下来。

对数组的理解:数组是一种容器,用来存储相同数据类型的元素,数组属于引用类型,其长度在运行期间不可改变。

数组下标从 0 开始,到 lenth - 1 ,即下标的合法区间为:[ 0, lenth - 1 ]

数组下标一旦不在合法区间中,会报一个 ArrayIndexOutOfBoundsException (数组下标越界异常)的异常

数组长度可以通过 数组名称.lenth 获取

数组的两种声明或定义方式

//第一种声明方式 首选!
dataType[] arrayName;
int[] arr1; // 数组的声明

//第二种声明方式 
dataType arrayName[];

java 使用 new 关键字为数组进行申请内存

数组的两种初始化方式

  • 动态初始化(长度已知)
dataType[] arrayName = new dataType[arrayLenth];
int[] arr2 = new int[3];
// 或者
dataType[] arrayName;
arrayName = = new dataType[arrayLenth];
int[] arr3;
arr3 = new int[3];
  • 静态初始化(内容已知)
// 基本(标准)格式
dataType[] arrayName = new dataType[]{elem1, elem2, ……};
int[] arr4 = new int[]{1, 2, 3};
// 或者
int[] arr5;
arr5 = new int[]{1, 2, 3};

// 省略格式
dataType[] arrayName = {elem1, elem2, ……};
int[] arr6 = {1, 2, 3};

在这里插入图片描述

注:

  • 虽然静态初始化没有直接指明数组长度,但是根据大括号里面的元素具体内容,也可以自动推算出来长度
  • 静态初始化和动态初始化可以拆分成声明和初始化两个步骤,但使用省略格式的静态初始化,就不能拆分成为两个步骤了
  • 不要同时使用静态初始化和动态初始化,也就是说,不要在进行数组初始化时,即为数组指定长度,又为数组里的元素指定初始化。
  • 定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。
  • 实际的数组对象被存储在堆(heap)内存中;
  • 如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈(stack)内存中。

数组的特点

  1. 数组的长度是确定,数组一旦被创建,在程序运行期间其大小是不可改变的
  2. 数组中的元素可以是基本类型,也可以是引用类型,但必须是同一种类型
  3. 数组变量属于引用类型,可以看成是对象,数组里的每个元素可以看成是数组的成员变量
  4. Java 中 new 出来的对象存放在堆(Heap)中,数组变量可以看成是对象,因此数组对象也存放在堆中

数组的隐式默认初始化

数组一旦被创建(动态初始化),如果不特意为数组元素赋值,会有一个默认的隐式赋值

数组元素的的数据类型 默认值
整型 0
浮点型 0.0
字符型 \u0000(一个空白符)
布尔型 false
引用类型 null
// 以下静态初始化,如果不指定内容,则打印结果为什么都没有
int[] arr2 = new int[]{};
int[] arr3 = {};
// 动态初始化,整型元素默认值为 0
int[] arr4 = new int[4];

posted on   demo-arch  阅读(52)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用

统计

点击右上角即可分享
微信分享提示