随心所欲不逾矩
1. 第一个 Java 程序
简单的 Java 程序,它将输出字符串 Hello World
java
public class HelloWorld {
/* 第一个Java程序
* 它将输出字符串 Hello World
*/
public static void main(String[] args) {
// 输出 Hello World
System.out.println("Hello World");
}
}
2. Java 关键字与保留字
定义:被 Java 语言赋予了特殊含义,用做专门用途的字符串。
特点:关键字中所有字母都是小写,Java 关键字,这些关键字不能用于常量,变量,和任何标识符名称。官网地址
下面列出了 Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。摘自菜鸟教程
类别 | 关键字 | 说明 |
---|---|---|
访问控制 | private | 私有的 |
protected | 受保护的 | |
public | 公共的 | |
default | 默认 | |
类、方法和变量修饰符 | abstract | 声明抽象 |
class | 类 | |
extends | 扩充,继承 | |
final | 最终值,不可改变的 | |
implements | 实现(接口) | |
interface | 接口 | |
native | 本地,原生方法(非 Java 实现) | |
new | 新,创建 | |
static | 静态 | |
strictfp | 严格,精准 | |
synchronized | 线程,同步 | |
transient | 短暂 | |
volatile | 易失 | |
程序控制语句 | break | 跳出循环 |
case | 定义一个值以供 switch 选择 | |
continue | 继续 | |
default | 默认 | |
do | 运行 | |
else | 否则 | |
for | 循环 | |
if | 如果 | |
instanceof | 实例 | |
return | 返回 | |
switch | 根据值选择执行 | |
while | 循环 | |
错误处理 | assert | 断言表达式是否为真 |
catch | 捕捉异常 | |
finally | 有没有异常都执行 | |
throw | 抛出一个异常对象 | |
throws | 声明一个异常可能被抛出 | |
try | 捕获异常 | |
包相关 | import | 引入 |
package | 包 | |
基本类型 | boolean | 布尔型 |
byte | 字节型 | |
char | 字符型 | |
double | 双精度浮点 | |
float | 单精度浮点 | |
int | 整型 | |
long | 长整型 | |
short | 短整型 | |
变量引用 | super | 父类,超类 |
this | 本类 | |
void | 无返回值 | |
保留关键字 | goto | 是关键字,但不能使用 |
const | 是关键字,但不能使用 |
注:Java 的 null
不是关键字,类似于 true
和 false
,它是一个字面常量,不允许作为标识符使用。
3. Java 标识符
3.1 标识符说明
Java 所有的组成部分都需要名字。类名,变量名以及方法名都被称为标识符 (自己可以起名字的地方都叫标识符)
3.2 标识符命名规则
关于 Java 标识符,有以下几点需要注意
- 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始
- 首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
- 关键字不能用作标识符
- 标识符是大小写敏感的
- 合法标识符举例:age、$salary、_value、__1_value
- 非法标识符举例:123abc、-salary
3.3 Java 中的名称命名规范
- 大小写敏感
- 包名:多单词组成时所有字母都小写:xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词的首字母大写:MyFirstJavaClass 大驼峰
- 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
- 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
注:
- 源文件名称必须和类名相同。当保存文件的时候,应该使用类名作为文件名保存,如果文件名和类名不相同则会编译错误。
- 在起名字时,为了提高阅读性,要尽量有意义,"见名知意"。
- Java 采用 unicode 字符集,因此标识符也可以使用汉字声明,但是不建议使用。
4. Java 变量
4.1 变量
变量的概念:
- 内存中的一个存储区域
- 该区域有自己的名称(变量名)和类型(数据类型)和值
- Java 中的每个变量必须先声名,再赋值,然后才能使用
- 该区域的数据可以再同一类型范围内不断变化
- Java 中的变量有四种基本属性:变量名,数据类型,存储单元跟变量值
Java 语言支持的变量类型:
- 类变量:独立于方法之外的变量,用 static 修饰
- 实例变量:独立与方法之外的变量,不用 static 修饰
- 局部变量:类的方法中的变量
注:这里后期详细补充
5. 数据类型
5.1 整数类型
byte、short、int、long
类型 | 占用存储空间 | 表数范围 |
---|---|---|
byte | 1字节=8bit位 | -128 ~ 127 |
short | 2字节 | -2^15~ 2^15-1 |
int | 4字节 | -2^31~ 2^31-1 (约21亿) |
long | 8字节 | -2^63~ 2^63-1 |
注:声明 long 类型常量需要再后面加 "L" / "l"
5.2 浮点类型
float、double
类型 | 占用存储空间 | 表数范围 |
---|---|---|
单精度float | 4字节 | -3.403E38 ~ 3.403E38 |
双精度double | 8字节 | -1.798E308 ~ 1.798E308 |
注:Java 的浮点型常量默认为 double 类型,声明 float 类型常量需要在后面加"F" / "f"
案例:圆的面积
定义圆周率并赋值为3.14,现有3个圆的半径分别为1.2、2.5、6,求它们的面积
java
/**
* 圆的面积
*
* @Author myf15609
* @Date 2023/4/2
*/
public class Exercise1 {
public static void main(String[] args) {
double PI = 3.14;
double radius1 = 1.2;
double radius2 = 2.5;
int radius3 = 6;
System.out.println("第一个圆的面积:" + PI * radius1 * radius1);
System.out.println("第二个圆的面积:" + PI * radius2 * radius2);
System.out.println("第三个圆的面积:" + PI * radius3 * radius3);
}
}
/*
第一个圆的面积:4.521599999999999
第二个圆的面积:19.625
第三个圆的面积:113.03999999999999
*/
案例:温度转换
小明要到美国旅游,可是那里的温度是以华氏度为单位记录的。 它需要一个程序将华氏温度(80度)转换为摄氏度,并以华氏度和摄氏度为单位分别显示该温度
java
/**
* 温度转换
*
* @Author myf15609
* @Date 2023/4/2
*/
public class Exercise2 {
public static void main(String[] args) {
double hua = 80;
double she = (hua - 32) / 1.8;
System.out.println("华氏度" + hua + "℉转为摄氏度是" + she + "℃"); // 华氏度80.0℉转为摄氏度是26.666666666666664℃
}
}
5.3 字符型
char 2个字节
- char 类型是一个单一的 16 位 Unicode 字符
- 最大值是 \u0000(十进制等效值为 0)、最大值是 \uffff(即为 65535)
- char 数据类型可以存储任何字符,char 类型是可以进行运算的,因为都是对应的 Unicode 码
- 可以使用转义字符 '' 来将其后的字符转变为特殊字符型常量
- 例如:char c1 = '1'、char c2 = '中'、char c3 = '\u0234';
java
class VariableTest3 {
public static void main(String[] args) {
double d1 = 12.3;
System.out.println(d1 + 1);
float f1 = 12.5F;
System.out.println(f1);
char c1 = 'a';
System.out.println(c1);
char c2 = '\n';
System.out.println("hello" + c2);
char c3 = '\t';
System.out.println(c3 + "world");
char c4 = '\u0043';
System.out.println(c4);
}
}
5.4 布尔类型
Boolean
- Boolean 类型用来判断逻辑条件,一般用于程序流程控制
- Boolean 类型数据值允许:true、false、不可使用 0 或非0的整数替代 false 或 true ,这点和 C 语言不同
- Java 虚拟机中没有任务供 Boolean 值专用的字节码指令,Java 语言表达式所操作的 Boolean 值,在编译之后都使用 Java 虚拟机中的 int 数据类型来替代,true 用 1 表示,false 用 0 表示
java
class VariableTest2 {
public static void main(String[] args) {
boolean isb1 = true;
if(isb1) {
System.out.println("禁止入内");
}else{
System.out.println("可以参观");
}
}
}
5.5 Java 常量
常量在程序运行时是不能被修改的
在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似,虽然常量名也也可以用小写,但是为了便于设别,通常使用大写字母表示常量。
final double PI = 3.1415926;
Java 语言支持一些特殊的转义字符序列
符号 | 字符含义 |
---|---|
\n | 换行 (0x0a) |
\r | 回车 (0x0d) |
\f | 换页符(0x0c) |
\b | 退格 (0x08) |
\0 | 空字符 (0x0) |
\s | 空格 (0x20) |
\t | 制表符 |
\" | 双引号 |
\' | 单引号 |
\\ | 反斜杠 |
\ddd | 八进制字符 (ddd) |
\uxxxx | 16进制Unicode字符 (xxxx) |
5.6 自动类型转换
- 自动类型转换:容量小的类型自动转为容量大的数据类型。数据类型按容量大小排序如下
- 此时的容量大或小,并非指占用内存空间的大小,而是指表示数据的范围的大小
- 有多种类型的数据混合运算时,系统首先自动将所有数据类型转为容量最大的那种数据类型,然后再进行计算
- byte,short,char 之间不会相互转换,三者的计算首先转为 int 类型
- Boolean 类型不能和其它数据类型运算
- 当把任何基本数据类型的值和字符串(String)进行链接运算时(+),基本数据类型的值都将自动转化为字符串(String)类型
菜鸟教程提到的数据类型转换规则
- 不能对 boolean 类型进行类型转换
- 不能把对象类型转换成不相关类的对象
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换
- 转换过程中可能导致溢出或损失精度
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
java
class VariableTest4 {
public static void main(String[] args) {
byte b1 = 2;
int i1 = 129;
// byte b2 = b1 + i1;
int i2 = b1 + i1;
long l1 = b1 + i1;
float f1 = b1 + i1;
System.out.println(i2); //131
System.out.println(l1); //131
System.out.println(f1); //131.0
char c1 = 'a'; //97
int i4 = c1;
System.out.println(i4);//97
int i3 = 10;
int i5 = c1 + i3;
System.out.println(i5); // 107
}
}
注:c1 的值为字符a,查 ASCII 码表可知对应的 int 类型值为 97,所以 i5 = 97 + 10
一些特殊情况
- 当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时
java
int i = 'A';//char自动升级为int,其实就是把字符的编码值赋值给i变量了
double d = 10;//int自动升级为double
long num = 1234567; //右边的整数常量值如果在int范围呢,编译和运行都可以通过,这里涉及到数据类型转换
//byte bigB = 130;//错误,右边的整数常量值超过byte范围
long bigNum = 12345678912L;//右边的整数常量值如果超过int范围,必须加L,显式表示long类型。否则编译不通过
- 当存储范围小的数据类型与存储范围大的数据类型变量一起混合运算时,会按照其中最大的类型运算
java
int i = 1;
byte b = 1;
double d = 1.0;
double sum = i + b + d;//混合运算,升级为double
- 当byte、short、char数据类型的变量进行算术运算时,按照 int 类型处理
java
byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2;// 编译报错,b1 + b2自动升级为int
char c1 = '0';
char c2 = 'A';
int i = c1 + c2;// 至少需要使用int类型来接收
System.out.println(c1 + c2);// 113
5.7 强制类型转换
java
class VariableTest5 {
public static void main(String[] args) {
int i1 = 123;
byte b = (byte)i1;
System.out.println(b); // 123
}
}
5.8 隐含强制类型转换
- 整数的默认类型是 int
- 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f
5.9 字符串 String
java
/*
1. String 属于引用数据类型
2. 声明 String 类型变量时,使用一对 ""
3. String 可以和8种基本数据类型变量做运算,且运算只能是链接运算 +
4. 运算的结果仍然是 String 类型
*/
class VariableTest6 {
public static void main(String[] args) {
String s1 = "Hello Bike";
System.out.println(s1); // Hello Bike
int number = 1001;
String numberStr = "学号";
String info = numberStr + number;
System.out.println(info);
boolean b1 = true;
String info1 = info + b1;
System.out.println(info1); // 学号1001true
// String info2 = number + b1 + numberStr; // 编译不通过,因为 int 类型不能和 boolean 运算
}
}
案例:身份登记
要求填写自己的姓名、年龄、性别、体重、婚姻状况(已婚用true表示,单身用false表示)、联系方式等等
java
/**
* @Author myf15609
* @Date 2023/6/19
*/
public class Info2 {
public static void main(String[] args) {
String name = "lanyecheng";
int age = 30;
char gender = '男';
double weight = 135.5;
boolean isMarried = true;
String phoneNumber = "177****0143";
System.out.println("name = " + name + ",age = " + age + ",gender = " + gender + ",weight = " +
weight + ",isMarried = " + isMarried + ",phoneNumber = " + phoneNumber);
}
}
5.10 引用数据类型
注:这里后期详细补充
6. ASCII 码、Unicode 编码、UTF-8
了解:ASCII 码
-
在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有0 和1 两种状态,因此8个二进制位就可以组合出256 种状态,这被称为一个字节(byte)。一个字节一共可以用来表示256 种不同的状态,每一个状态对应一个符号,就是256 个符号,从0000000 到11111111。
-
ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,比如空格"SPACE"是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
-
缺点:
- 不能表示所有字符。
- 相同的编码表示的字符不一样:比如,130 在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel(ג)。
了解:Unicode 编码
-
乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
-
Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用Unicode 没有乱码的问题。
-
Unicode 的缺点:Unicode 只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储:无法区别Unicode 和ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费
了解:UTF-8
- UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。
- UTF-8 是一种变长的编码方式。它可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度。
- UTF-8的编码规则:
- 对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)。
- 对于多字节的UTF-8编码,如果编码包含n 个字节,那么第一个字节的前n位为1,第一个字节的第n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为"10",其余6位用来对字符进行编码。
7. 进制之间的转换
-
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位
-
二进制的整数有如下三种形式:
- 原码:直接将一个数值换成二进制数。最高位是符号位
- 负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
- 负数的补码:其反码加1。计算机以二进制补码的形式保存所有的整数。
- 正数的原码、反码、补码都相同,负数的补码是其反码+1
为什么要使用原码、反码、补码表示形式呢?
计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法.
我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了
- 对于正数来讲:原码、反码、补码是相同的:三码合一。
- 计算机底层都是使用二进制表示的数值。
- 计算机底层都是使用的数值的 补码 保存数据的。
进制转换
- 二进制转成十进制乘以2的幂数
- 十进制转成二进制除以2取余数