总览

Java 语言中有 50 个关键字,这些关键字不能用作标识符,如下图所示(来自 jls8)

图片描述

其中关键字 const 和 goto 是预留的,现在无法使用,并且在程序中出现会是编译器产生错误信息。

true 和 false 也许看起来像是关键字,但是他们专门用于表示布尔类型的字面量。类似的, null 专门用于表示 Null 类型的字面量。

其中 strictfp 始于 1.2,assert 始于 1.4, enum 始于 1.5, 这里说的都是 JDK 的版本。

下面我们先开始将关键词分类,无法的分类的关键词将分开讲解。

归类

基本类型

  1. char

  2. boolean

  3. double float

  4. byte int long short

共计 8 中类型的基本类型,占据了 Java 的 8 的关键字。
下面简单介绍一下,从最简单的开始。

boolean

很简单,非真即假,有两个字面量,true 和 false。 值得注意的是,在 Java 中整形值和布尔值之间不能相互转换,至少在语言层面。网上有关 boolean 在内存中占用多大空间,这涉及到一个设计与实现的问题,Java 语言的规范和 Java 虚拟机的规范和最终实现的 Java 虚拟机的实现总会有实现上的语意偏离,而 Java 虚拟机的规范的原则也是在保证正确性的情况下尽量让虚拟机的实现提升效率。

相关的操作:

  1. == != 等于 不等于

  2. ! 取反

  3. & ^ | 位与 异或 或

  4. && || 条件与 条件或

  5. ? : 三目运算符

  6. 在控制流程中使用(if, while, do, for)

一个布尔值可且仅可被转型为 boolean, Boolean, Object 类型。

char

char 类型用于表示单个字符。
而关于 char 的长度是个非常有趣的问题,我们首先需要了解编码的相关知识。
可以看一下吴秦的博客,总结的很好。

在 Java 语言中字符编码是基于 Unicode 编码规范中的 UTF-16 实现的,UTF-16 具体定义了 Unicode 字符在计算机中的存取方法,UTF-16 使用定长的两个字节来表示 Unicode 的转换格式,也是16位长度,理论上可以表示
65536 个字符,然后在当时足够长的 char 类型在加入大量东亚体系的表意文字后, 16 位的 char 类型已经不能描述所有的 Unicode 字符了。

对此 Java 的对应策略可以参照 魏照哲的专栏 进行理解,学习完上面两篇博客和 Java 既有的字符表现形式,对于 char 长度这个问题大家应该要慎重对待。

byte short int long (Java 整型)

Java 的整型的范围是与机器无关的(这与 C,C++ 正好相反),因为 Java 程序时运行在 Java 虚拟机之上的,各个平台的上的 Java 虚拟机遵循同样的 Java 虚拟机规范。

这里再讲一些关于整型字面量表示的内容:

// 注意 '0' 是零 不是 字母 o 或 O
int a = 077;   // 前面加 '0' 表示八进制数, 十进制 63
int b = 0xee;  // 前面加 '0x' 或 '0X',后面的 ee 也可以表示成 EE、Ee、eE 表示十六进制,十进制238
int c = 0b00000001; // 前面加 '0b' 或 '0B',表示十六进制,十进制 1 ,JDK 1.7 增加的

另外顺便说下在整形字面量和浮点数中使用下划线的特性(也是JDK 1.7 增加的)

int a = 1_500_000; // 方便阅读
float b = 5_6.3_4;
// 需要注意的是不能以 '_' 开头,只能出现在数字中间,包括不能出现在进制标示的后面 '0x_EF' 这样不合法

float double

怎么说呢,它们无法精确的表示所有数,对于很多数而言,是存在误差的。
大家先看篇博客,我去喝杯咖啡

流程控制

  1. if else switch case

  2. while do for

  3. break 用于退出 switch 和 当前循环,另外支持标签跳出多重循环

  4. continue 用于结束本轮循环,从下轮循环开始执行

共计 9 个关键字。

关于流程控制关键字这里只讲一下 switch :
case: 标签可以是:

  1. char, byte, short, int, Character, Byte, Short, Integer

  2. enum 枚举类型

  3. String 字符串字面量 (JDK 1.7 增加),实际上是利用 hash 算法转化为 int 类型的语法糖

访问控制符

包括 public protected private

访问控制符决定了其他类是否可以使用特定的域或调用特定的方法。访问控制分为两个层次:

  • 顶层,可以修饰类,public, package-private (不需要显式修饰).

  • 成员层面,public, private, protected 或者 package-private (不需要显式修饰).

被声明为 public 的类对所有类可见,没有显式修饰的类只在包内可见。
关于成员的可见性,给出下图以供理解:
图片描述

包相关

  1. package

  2. import

包是我们用来分类相同功能模块的类、接口文件的一个集合,就像我们电脑中文件夹一样。声明在类或接口文件的头部,如下所示:
package packageName
关于包我们需要牢记的一点是,相同前缀的包除了可以在组织上在一起,但是实际上他们没有任何关系:
例如 com.sun.a 和 com.sun 作为两个包没有任何关系,属于独立的类集合。

既然包已经将我们类组织起来,那么我们如何来使用包中个类的?
我们可以像下面一样使用类的全限定名:

java.util.Date date = new java.util.Date(); 
// 假如你一直这么干,那么恭喜你,你对 JDK 中常用类分布一定非常熟悉
// 假如你一直这么干,并且使用黑轴的机械键盘,那么很不幸,你手指一定非常酸痛

这时 import 关键字就登场了,我们可以这样:

import java.util.Date;
...
Date date = new Date();

实际上在这里我必须要提前讲到 static 关键字,JDK 1.5 起支持静态导入:

// 让我们可以不同导入 Math 类再使用 PI 静态变量
import static java.lang.Math.PI;   
public  class MathUtils{   
    //计算圆面积   
    public static double calCircleArea(double r){   
        return PI * r * r;   
    }   
    //计算球面积   
    public static double calBallArea(double r){   
        return 4 * PI * r * r;   
    }   
}   

面向对象

对于各种编程范式,没有本质上的优劣,都是为了更好的解决问题而存在的,我们需要权衡利弊,简单就是一种美。
下面有几篇文章是关于面向对象一些内容,大家可以看看:
Wiki的词条 ------ 如何理解面向对象
代码重构的一个例子 -------- 各种流行的编程方式
有时候走得太远,我们都忘了我们为何出发,不忘初心,不仅对于梦想,对程序设计也是如此。

开始将涉及的关键字再次分类:

  1. class interface

  2. extends implements

  3. abstract static native

  4. new

  5. instanceof

  6. this super

  7. return

  8. void
    这部分内容涉及面太广,大家自己看看书吧,哈哈。

异常处理

五连发
try catch finally throw throws

并发与同步

三连发
final volatile sychronized
final 基础用法
内存模型系列文章 建议大家看完这一系列文章

什么鬼的其他

五连发
enum default assert strictfp transient

enum

先看用法----》源码解析---》一篇e文

default

在 switch 语句的的使用:
int i=3;
switch(i)
{
   case 1:
       System.out.println(1);
       break;
   case 2:
       System.out.println(2);
       break;
   case 3:
       System.out.println(3);
       break;
   default:
       System.out.println("default");
       break;
} 
在注解中的使用

不了解注解的朋友可以先看几篇文章Java 注解指导手册-----注解的实现-曹旭东的回答

关于 default 在注解中的使用
来自 Java Language Specification 8 9.6.2 章节
An annotation type element may have a default value, specified by following the
element's (empty) parameter list with the keyword default and an ElementValue

Default values are not compiled into annotations, but rather applied
dynamically at the time annotations are read. Thus, changing a default
value affects annotations even in classes that were compiled before
the change was made (presuming these annotations lack an explicit
value for the defaulted element)

public @interface RequestForEnhancementDefault {
    int id(); // No default - must be specified in each annotation
    String synopsis(); // No default - must be specified in each annotation
    String engineer() default "[unassigned]";
    String date() default "[unimplemented]";
}
interface default method (JDK 1.8)

我就不瞎比比了,大家看下几篇介绍文章:
天马流星拳------圆月弯刀

assert

在各种测试框架大行其道的背景,这个关键字的使用,应该仅限于简单的程序测试,需要注意的是断言机制是否生效需要的显式地指定 JVM 运行参数。参考 Programming With Assertions

strictfp

引用 stackoverflow 上的一个回答来终结这个关键字

It all began with a story,

When java was being developed by James Gosling, Herbert and rest of
his team. They had this crazy thing in mind called platform independency.
They wanted to make oak(Java) so much better that it
would run exactly same on any machine having different instruction
set, even running different operating systems. But, there was a
problem with decimal point numbers also known as floating point and
double in programming languages. Some machines were built targeting
efficiency while rest were targeting accuracy. So, the later(more
accurate) machines had size of floating point as 80 bits while the
former(more efficient/faster) machines had 64 bit doubles. But, this
was against there core idea of building a platform independent

  1. Also, this might lead to loss of precision/data when a code

  2. built on some machine(having double of 64 bit size) and run on

another kind of machine(having double of 80 bit size).

Up-Sizing can be tolerated but Down-Sizing can't be. So, they came
across a concept of strictfp i.e. strict floating point. If you use
this keyword with a class/function then its floating point and doubles
have a consistent size over any machine. i.e. 32/64 -bit respectively.

transient

给出几篇文章来循序渐进地解决这个关键字
序列化用法--->深入分析序列化--->单独说下transient关键字---》序列化高级认知---》序列化中那些你不知道的5件事---》使用SealedObject & SignedObject对序列化加密解密(只需要关注SealedObject & SignedObject 加解密这部分)


Jacendfeng
544 声望23 粉丝

爱豆瓣,爱知乎,爱电影,KTV垃圾麦主,专注Java 服务器端开发,技术文章整理者。