1.Java入门与数据类型

Java 入门:变量、数据类型和类型转换
写程序时,我们总要保存一些数据,比如年龄、姓名、价格。先把变量和类型弄清楚,后面的计算与对象就好理解了。我们从运行第一个程序开始。
1. 先认识 JDK、JVM 和 IDEA
- JDK:写 Java 程序需要的工具,里面有编译器和运行工具。
- JVM:负责执行编译后的 Java 程序。
- IDEA:写代码的软件,帮助我们编辑、运行和调试。
学习时安装完整 JDK,再让 IDEA 的项目使用这个 JDK 就可以了。终端中输入 java -version、javac -version,可以检查是否配置成功。
编译器先把源码变成字节码,JVM 再执行它,所以运行程序可以分成下面两步:
text
HelloJava.java → 编译 → HelloJava.class → JVM 执行
java
public class HelloJava {
// 程序从 main 开始执行,下面这句把文字输出到控制台。
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
main 是程序的入口,println 用来输出内容。先看懂里面的输出语句即可,暂时不必一次理解入口里的所有关键字。
在文件所在目录执行:
shell
javac -encoding UTF-8 HelloJava.java
java HelloJava
文件名要与 public class 后面的类名一致。运行时写类名,不加 .class。
后面的简单例子只展示 main 里的语句,避免反复写入口。遇到 import 时,它仍应放在类声明之前。
2. 变量:给一个值取名字
变量用来保存数据。声明时要说明类型、名字和初始值,例如 int num = 1。
有了名字,就可以在后面的代码中读取或修改这个值,不用关心它具体放在内存的哪个位置。
先保存 1,再改成 2;不允许重新赋值的变量加上 final:
java
int num = 1;
// 重新赋值后,num 保存的是新值,原来的 1 被替换。
num = 2;
System.out.println(num); // 2
// 加上 final 后,不能再给 num1 重新赋值。
final int num1 = 1;
System.out.println(num1); // 1
num 可以重新赋值,num1 不可以。这里说的是变量保存的值不能重新赋值;如果它保存的是对象引用,不代表对象里面的内容也不能变化,第四节会再看这个区别。
final 修饰类时,类不能被继承;修饰方法时,方法不能被子类重写。
3. 八种基本数据类型
数据类型说明一个值是什么样的数据。年龄通常是整数,价格可能带小数,是否及格则只有真假。
分清类型,Java 才能判断这个值能做哪些运算、能放进哪个变量。先认识这八种基本类型:
| 类型 | 用途 | 大小 | 例子 |
|---|---|---|---|
byte |
小范围整数,-128~127 | 8 位 | byte level = 10; |
short |
整数,-32768~32767 | 16 位 | short count = 1000; |
int |
常用整数 | 32 位 | int age = 18; |
long |
更大范围的整数 | 64 位 | long total = 3000000000L; |
float |
小数 | 32 位 | float rate = 0.5F; |
double |
常用小数 | 64 位 | double price = 19.9; |
char |
一个 UTF-16 字符单元 | 16 位 | char grade = 'A'; |
boolean |
真或假 | Java 没有规定统一存储大小 | boolean passed = true; |
long 的大整数字面量加 L,float 的小数字面量加 F。
'A' 用单引号;"Java" 用双引号,是 String。String 不属于八种基本类型。
java
int age = 18;
double price = 19.9;
char grade = 'A';
boolean passed = true;
// 单个字符用 char,姓名这样的文字用 String。
String name = "张三";
System.out.println(name + ",年龄:" + age);
System.out.println(price);
System.out.println(grade);
System.out.println(passed);
4. 引用:两个变量可以使用同一个对象
引用可以先理解为“通过它找到并使用一个对象”。数组和普通对象都通过引用来使用。
我们经常会把一个对象交给不同代码使用,因此要分清:复制一个引用,不等于复制出一个对象。看下面这次赋值:
java
int[] first = {80, 90};
// 没有复制数组,两个变量指向的是同一个数组。
int[] second = first;
second[0] = 100;
System.out.println(first[0]); // 100
final int[] scores = {60, 70};
// final 限制重新赋值给 scores,但数组里的元素仍然可以修改。
scores[0] = 80;
System.out.println(scores[0]); // 80
first、second 使用同一个数组,所以通过 second 改动元素,first 也能看到。
final 限制的是变量重新赋值。scores 不能换成另一个数组,但数组里的元素仍可以修改。
5. 类型转换
5.1 自动转换
类型转换就是把一个类型的值,作为另一个类型来使用。比如现有数量是 int,接下来想用 long 保存。
这种兼容的转换可以自动完成,不需要自己写转换符号。
5.2 强制转换
有些转换需要我们明确表示“我要这样转”,比如把带小数的价格转换成整数。这时写 (int)。
小数部分会被去掉,不是四舍五入。把自动转换、强制转换和整数除法放在一起观察:
java
int count = 100;
long total = count;
System.out.println(total); // 100
double price = 12.9;
// 转成整数会舍去小数部分,不是四舍五入。
int number = (int) price;
System.out.println(number); // 12
// 两个整数相除只得到整数;有小数参与时,才做浮点除法。
System.out.println(5 / 2); // 2
System.out.println(5 / 2.0); // 2.5
两个整数相除,结果仍是整数。想保留小数,可以让其中一个数成为小数。
5.3 转换也可能丢失数据
自动转换不一定精确,比如某些较大的 int 转成 float 会丢失精度。强制转换到范围更小的整数类型,还可能得到与原值差很多的结果。
java
int value = 16777217;
// 自动转换也可能丢失精度:这个整数超出了 float 的精确整数范围。
float approximate = value;
System.out.println((int) approximate); // 16777216
int tooLarge = 130;
// 130 超出了 byte 的范围,强转后的值不再是 130。
System.out.println((byte) tooLarge); // -126
int max = Integer.MAX_VALUE;
System.out.println(max + 1); // -2147483648
// 先转成 long 再相加,避免加法先在 int 范围内溢出。
System.out.println((long) max + 1); // 2147483648
最后两行说明:int 超出范围不会自动变成 long。需要更大范围时,要先转换,再计算。
6. 内存知识先这样理解
- 堆:可以先理解为存放对象和数组的地方。
- 栈:与线程的方法调用有关,记录当前调用中的局部变量等信息。
不要记成“基本类型一定在栈,引用类型一定在堆”。例如,对象里的 int age 是对象的一部分,也不是独立放在方法栈里的局部变量。
JMM 是另一件事:它主要解释多线程之间怎样看见共享数据的变化。学多线程时再深入即可。
7. 常见存储单位
| 单位 | 换算 |
|---|---|
| 1 B(字节) | 8 bit(位) |
| 1 KiB | 1024 B |
| 1 MiB | 1024 KiB |
| 1 GiB | 1024 MiB |
严格写法中,kB、MB 使用 1000 倍;有的软件却把 1024 倍也写成 KB、MB,阅读容量时要注意。
8. 先记住这几件事
String是引用类型,不是基本类型。final变量不能重新赋值,但对象内容不一定不能改。- 复制引用不等于复制对象。
- 整数除法去掉小数;强制转换不会帮你检查所有越界情况。

评论