☰
Java基础篇(2)——Java基础语法
2026/10/15 19:00:01 网站建设 项目流程

1. 语法结构

1. 包声明:必须在文件顶部

2. 导入语句:导入用到的其他类

3. 类定义:定义class类,主类的类名要和文件名一致,大驼峰命名

4. main方法:程序入口

package com.example.demo; // 包声明 import java.util.Scanner; // 导入 public class HelloWorld { // 类名 // 程序入口 public static void main(String[] args) { System.out.println("Hello World!"); } }

2. 命名规范

基本规范:

  • 只能包含数字,字母,下划线_,美元符$
  • 不能以数字开头
  • 不能使用Java中的关键字(如 class,void,int...)
  • 严格区分大小写
  • 需要做到在命名类、对象或变量时,能够望文生义(尽量采用英文命名)

大驼峰命名:指每个单词的首字母都大写(例如:StudentInfo,StudentMangager...),通常用于类的命名

小驼峰命名:指第一个单词首字符小写,后续单词首字符大写(例如:studentName,studentId...),通常用于给变量命名

定义常量命名:全部字母都大写,多个单词之间用下划线_分隔(例如:MAX_VALUE,MIN_VALUE...)

包名命名:全部为小写字母,一半是用公司域名倒写(com.example.demo)

3. Java的八大基本类型

基本类型是Java中最基础的数据类型,它直接存储在栈内存中,操作速度快

  • 整型:
    • byte:
      • 占用字节:1字节(Byte) = 8位(bit)
      • 默认值:0
      • 取值范围:-128 ~ 127
      • 对应包装类:Byte
    • short:
      • 占用字节:2字节
      • 默认值:0
      • 取值范围:-32768 ~ 32767
      • 对应包装类:Short
    • int:
      • 占用字节:4字节
      • 默认值:0
      • 取值范围:-2^31 ~ 2^31-1
      • 对应包装类:Integer
    • long:
      • 占用字节:8字节
      • 默认值:0L(数值后必须加 “ L ”)
      • 取值范围:-2^63 ~ 2^63-1
      • 对应包装类:Long
  • 浮点型:
    • float(单精度):
      • 占用字节:4字节
      • 默认值:0.0f (数值后必须加 " F " 或 " f ")
      • 对应包装类:Float
    • double(双精度):
      • 占用字节:8字节
      • 默认值:0.0d(后缀d可省略)
      • 对应包装类:Double
  • 字符型:
    • char:
      • 占用字节:2字节
      • 默认值:'\u0000' (Unicode转义空字符)
      • 取值范围:0 ~ 65535
      • 对应包装类:Character
  • 布尔型:
    • boolean:
      • 占用字节:1字节
      • 默认值:false
      • 取值范围:true 和 false
      • 对应包装类:Boolean

1. 为什么在Java中char是2个字节?

在Java中采用Unicode(UTF-16)编码,char是一个无符号整数,2字节也就是16位,能够表示范围:0~65535,在当时这个范围足以所有字符;后期Unicode扩展,对超出这个范围的字符采用两个char组合来表示

2. 为什么用char来表示字符而不是short?

Unicode编码是从0开始的,所有字符码点都是非负整数,char 类型就是无符号整数,所有都是正数,表示范围是0~65535,而short 类型最高位是符号位,用来表示正负,表示的范围就是-32767~32766,有一半为负数用不上的浪费了,且Unicode中的字符码点要大于32767,所以设计出char来专门表示字符

4. 包装类

基本数据类型对应的引用类型,就是把基本类型包装成对象,而对象默认值都是null

基本类型包装类示例
byteByteByte b = 10
shortShortShort s = 100
intIntegerInteger i = 5
longLongLong l = 100L
floatFloatFloat f = 3.14f
doubleDoubleDouble d = 3.14
charCharacterCharacter c = ' A '
booleanBooleanBoolean b = true

装箱拆箱方法:

自动装箱是 Java 编译器自动将基本类型转换为对应的包装类型,本质是调用valueOf()方法(例如 Integer a = 100; 等价于 Integer a = Integer.valueOf(100)),而拆箱则是包装类型转换成对应基本类型,本质是调用xxxValue()方法(例如 int b = a; 等价于 int b = a.intValue())

基本类型装箱方法拆箱方法
intInteger.valueOf( int i )Integer.intValue()
byteByte.valueOf( byte b )Byte.byteValue()
shortShort.valueOf( short s )Short.shortValue()
longLong.valueOf( long l )Long.longValue()
floatFloat.valueOf( float f )Float.floatValue()
doubleDouble.valueOf( double d )Double.doubleValue()
charCharacter.valueOf( char c )Character.charValue()
booleanBoolean,valueOf( boolean b )Boolean.booleanValue()

注:

  • 包装类都是由final来修饰的,不能被继承,且一旦创建,值不能被修改
  • 为了线程安全、缓存机制有效、以及一致性。不可变对象可以被安全地在多个线程间共享,且可以作 HashMap 的 key。
  • 包装类对象是在堆中存储,而引用是在栈中
  • Byte、Short、Integer、Long、Float、Double 继承自 Number 类,Character 和 Boolean 直接继承 Object

1. 为什么需要包装类?

在使用集合或泛型时,参数类型必须是对象类型,且包装类支持null,内置了很多工具方法

2. 缓存机制

提高性能,节省内存。频繁使用的数值被预先创建并复用。Byte,Short,Integer,Long缓存范围为-128~127,Character为0~127,Boolean的true和false都被缓存,而Float,Double浮点数是没有缓存的;

创建一个缓存范围内的对象实际上是从缓存中取的同一对象,超出缓存范围的则是新建对象:

// Integer 缓存范围:-128 ~ 127 Integer a = 100; Integer b = 100; System.out.println(a == b); // true(从缓存取,同一个对象) Integer c = 200; Integer d = 200; System.out.println(c == d); // false(超出缓存,新建对象) System.out.println(c.equals(d)); // true(用 equals 比较内容) Integer a = Integer.valueOf(100); // 从缓存取 Integer b = new Integer(100); // 强制创建新对象 System.out.println(a == b); // false

3. 浮点数取值范围没有缓存

因为浮点数取值范围太大,缓存所有值不现实,且浮点数使用频率不如整数高

4.Integer a = null; int b = a;

抛出NullPointerException。因为拆箱时调用 a.intValue(),而 a 为 null。

5.修饰符

修饰符是 Java 中用于修饰类、方法、变量、构造方法等的关键字,用来控制其访问范围、行为特性或继承关系。

访问修饰符:

  • public:公开访问,任何地方都可访问
  • protected:受保护,允许同一个类,同一个包及不同包的子类访问
  • default:默认(无修饰符),只允许同一个类和同一个包下访问
  • private:私有的,仅当前类可访问

非访问修饰符:

  • static:静态的,被修饰的东西表示是属于类的而非实例
  • final:不可变,表示不可被修改、继承、重写
  • abstract:抽象的,不可被实例化
  • synchronized:修饰线程,表示加锁保证线程安全
  • volatile:表示显示可见性,保证代码程序按照顺序执行

1. final、finally、finalize() 的区别?

  • final:修饰符,不可改变
  • finally:异常处理的最终执行块
  • finalize():垃圾回收前调用

2. synchronized 和 volatile 的区别?

  • volatile:保证可见性,不保证原子性,不能修饰类和方法
  • synchronized:保证可见性和原子性,性能较低

3. static的作用:修饰变量,方法,类,代码块

  • 静态变量:属于类的,所有对象共用一份,在类加载时进行初始化,JDK8 之前在方法区,JDK8+ 在堆中的 Class 对象里,可通过 类名.变量名进行访问,也可以通过对象引用访问
  • 静态方法:不需要创建对象,可直接通过 类名.方法名进行调用,没有隐式对象不能使用 this 和 super,只能访问静态成员(静态变量或其他静态方法)或通过对象引用来访问实例
  • 静态代码块:在类加载时自动执行且只执行这一次,多个静态代码块按照声明顺序进行执行,是在构造方法之前执行,常用于加载驱动或初始化变量
  • 静态内部类:独立于外部类,不能使用外部类引用,不用依赖于外部类创建,只能访问到外部类的静态成员,不能直接去访问外部类的实例成员
class Parent { static { System.out.println("Parent 静态代码块 1"); } { System.out.println("Parent 构造代码块"); } static { System.out.println("Parent 静态代码块 2"); } public Parent() { System.out.println("Parent 构造方法"); } } class Child extends Parent { static { System.out.println("Child 静态代码块 1"); } { System.out.println("Child 构造代码块"); } static { System.out.println("Child 静态代码块 2"); } public Child() { System.out.println("Child 构造方法"); } } public class Test { static { System.out.println("Test 静态代码块"); } public static void main(String[] args) { System.out.println("=== main 开始 ==="); new Child(); System.out.println("=== 第一次 new 结束 ==="); new Child(); System.out.println("=== main 结束 ==="); } }
Test 静态代码块 === main 开始 === Parent 静态代码块 1 Parent 静态代码块 2 Child 静态代码块 1 Child 静态代码块 2 Parent 构造代码块 Parent 构造方法 Child 构造代码块 Child 构造方法 === 第一次 new 结束 === Parent 构造代码块 Parent 构造方法 Child 构造代码块 Child 构造方法 === main 结束 ===

4. static修饰的方法为什么不能使用 this 和 super

static方法属于类,不属于对象;而this和super必须依附于具体的对象实例,即 this 指向堆内存中当前对象实例,super 指向父类实例的内存空间;静态方法被调用时,可能根本没有对象存在。

5. final修饰符作用:修饰变量,方法,类

  • 修饰变量:该变量不可再进行赋值,值不可改变,即为常量
  • 修饰方法:不能被子类重写,方法可重载
  • 修饰类:不能被继承

ps:

  • 重载通常是同一个类中,方法名相同,参数列表不同(参数个数,类型...),与返回值无关

  • 重写是指在子类中,重写实现父类的同一方法,方法名和参数列表必须相同,返回值类型相同或者是父类返回值的子类,抛出的异常不能比父类多

6.运算符

  • 算术运算符:用于数值运算
运算符作用示例
+加法运算,字符串拼接1+1 = 2,"a"+"b" = "ab"
-减法运算2-1 = 1
*乘法运算9*9 = 81
/除法运算(整型会舍弃小数部分)(int)5/2 = 2
%取余/取模(余数)5%2 = 1
++自增(+1)i++ = i+1
--自减(-1)i-- = i-1

注:

1. 自增和自减有前后缀之分,当使用 i++ 时,表示先使用的是 i 原先的值,后再继续 +1 操作,而++i 则是先 +1 再使用,同样 -- 也是一样的

2. 整型在除以0或对0去余时会直接抛出异常ArithmeticException;而浮点数则不会抛出异常,结果显示为 Infinity 无穷大 或 NaN非数字

  • 关系运算符:比较值之间的关系,结果为boolean型(Ture/False)
运算符作用示例
==等于a == b
!=不等于a != b
>大于a > b
<小于a < b
>=大于等于a >= b
<=小于等于a <= b

注:在比较引用类型时(例如String)== 号只比较他们的内存地址而不是具体的值,比较具体的值应使用 .equals() 方法

  • 逻辑运算符:用于条件判断,返回boolean
运算符作用示例
&逻辑并(条件同时成立时Ture)条件1 & 条件2
|逻辑或(有一个条件成立时Ture)条件1 | 条件2
&&短路并(条件1不成立,直接False不计算条件2)条件1 && 条件2
||短路或(条件1成立,直接Ture不计算条件2)条件1 || 条件2
!逻辑非(取反,条件成立则为False,不成立Ture)! 条件1
^逻辑异或(两边不同返回Ture,相同返回False)ture^false

注:利用 &&,|| 短路特性可以提高效率并避免潜在的空指针异常

  • 赋值运算符:
运算符作用示例
=直接赋值a = 1
+=加后赋值a += 1 等价于 a = a + 1
-=减后赋值a -= 1 等价于 a = a - 1
*=乘后赋值a *= 1 等价于 a = a * 1
/=除后赋值a /= 1 等价于 a = a / 1
%=取余赋值a %= 1 等价于 a = a % 1
其它运算...同理....

注:

在 Java 中,所有小于 int 的整数类型(byte、short、char)在进行算术运算时,都会自动提升为 int 类型,然后才进行计算,复合赋值运算符有隐式强转,例如:byte a = 1,在进行 a = a+2 的运算时,数字2是 int 型的,而运算中的 a 会从byte 升为 int,最后 int 型的结果又赋值给byte a,就可能出现精度丢失问题,所以这里如果是 a = a + 2,编译器就会报错需要进行强制类型转换,也就是 a = ( byte ) ( a + 2 ) 才可以通过编译,而使用 a += 2时,则会进行隐式强转,不会编译报错

拓展:

  • 位运算符:操作整数的二进制位(操作数必须是整数类型)
运算符作用示例
&位与运算(同1则1,不同则0)0b0101 & 0b0011 = 0b0001
|位或运算(有1则1,无1则0)0b0101 | 0b011 = 0b0111
^异或运算(不同为1,相同为0)0b0101 ^ 0b0011 = 0b0110
~取反运算(补码)~0b0101 = 0b1010
<<左移(低位补0)5 << 1 (移位数n)相当于乘以 2ⁿ
>>右移(高位补符号位,正数1负数0)-5 >> 1保留符号地除以 2ⁿ
>>>无符号右移(高位补0)-5 >>> 1把负数当成大正数来移位
  • 三元运算符:条件 ? 表达式1 : 表达式2,如果条件为true,取表达式1的值,否则取表达式2的值。例如:int max = (a > b) ? a : b;
  • instanceof 类型比较:String s = "Hello"; boolean result = s instanceof String;
  • 运算符优先级:可采用()来提高运算优先等级,明确运算顺序
    1. (最高)++,--,!,~
    2. *,/,%
    3. +,-
    4. <<,>>,>>>
    5. <,>,<=,>=,instanceof
    6. ==,!=
    7. &
    8. ^
    9. |
    10. &&
    11. ||
    12. ?:
    13. 赋值运算

括号 > 单目 > 算术 > 位移 > 关系 > 相等 > 位运算 > 逻辑 > 三元 > 赋值

补充:

1. 整数做除法运算时,如果想保留小数,可以将一个操作数转换成浮点型

例如:(double)a / b

2. == 号通常用于基本数据类型比较,在比较引用类型时,默认比较的是他们的地址

3. 不借助第三个变量来实现两个数值交换:

int a = 10; int b = 20; //1.算术运算加减法 a = a + b; // a = 30, b = 20 b = a - b; // b = 30 - 20 = 10, a = 30 a = a - b; // a = 30 - 10 = 20, b = 10 //2.异或运算 a = a ^ b; // a = 10 ^ 20, b = 20 b = a ^ b; // b = (10 ^ 20) ^ 20 = 10, a = 10 ^ 20 a = a ^ b; // a = (10 ^ 20) ^ 10 = 20, b = 10 //3.赋值表达式 //3.1 b = a + (a = b) * 0; //3.2 a = a + b - (b = a); //3.3 a = (a ^ b) ^ (b = a); //3.4 b = (a ^ b) ^ (b = a);

前不久我的一个朋友发信息给我,他说他最近很难过,他的发小Q,走了,自s的,把自己关在卫生间里,燃了很多木炭,一氧化碳中毒,是Q的妹妹发现的...

Q和他的爷爷奶奶一起生活,那时候Q的爷爷联系我那个朋友,说他们联系不上Q了,很担心他不知道去哪里,我那个朋友和Q的其他共同朋友也同样联系不上,后来我朋友收到消息,Q已经走了... 据我那个朋友所说,Q患有抑郁症,已经有好几年了,Q比我们大几岁,大学毕业后就一直在家没有出去工作,他得抑郁症好像是由于高中时候的一段感情经历,他们本来分手了,后来大学又有了联系,但具体什么样我那个朋友也不清楚,因为那时候Q的精神状态就不太对劲了,这些也没有和他或是其他朋友讲过,大概就是那种断崖式的吧,我也不太懂...

只是觉得很可惜吧,二十几岁啊,这是多么美好的年纪啊,从学校走向社会,能自己挣钱养活自己过自己的生活,又没有结婚房贷车贷的困扰,这是人生中真正属于自己的几年时光...

希望大家不管遇到什么困难,都要努力克服他,战胜他;解决问题可比解决自己要强的多,永远不要轻视生命,永远不要想着放弃。

非常推荐大家去读一本书《钢铁是怎么练成的》,或者是看00年拍的电视剧版,你也能成为自己的保尔柯察金

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询