Java从环境到类与对象 · SSH 实操

第一单元 · 终端、变量、输入 · 第 2 / 12 节

变量、类型与字符串拼接

用 int/double/char/boolean/String 保存数据,分清整数除法与小数除法,用 + 拼接字符串,用强制转换和 % 处理取整与余数。

约 30 分钟 · 6 个步骤 · 进度只存本机

把网页放左边,SSH 终端放右边。本节继续在终端里写 .java、编译、运行;所有代码都放在独立目录 ~/java-practice/lesson02,不碰 lesson01 的文件。

再提醒一次四种块:bash 块是要粘到终端的命令,java 块是源码,input 块是只读的输入示例,output 块是只读的程序输出;复制按钮只对前两种有效。

上一节 Hello 只会打印一句固定的话。这一节让程序记住数据:先给数据起名字、规定类型,再在后面的语句里使用。变量可以想成一个贴了标签的盒子:标签是变量名,盒子形状是类型,盒子里装的是值。Java 是“强类型”语言,盒子一旦声明成 int,就不能直接塞进 9.9 这样的小数;类型不匹配时编译器会拦住你。

类型能存什么字面量写法示例
int整数(没有小数点)18、-3、2026
double小数(双精度浮点数)9.9、12.5、3.0
char单个字符,用单引号'A'、'中'
boolean只有两个值:true / falsetrue、false
String一串文字,用双引号"小安"、"你好"

表里的“字面量”就是直接写在代码里的值,例如 18、9.9、'A'、"你好";它们不需要先读输入,也不是从变量里取出来的。double 是 Java 最常用的“浮点数”类型,浮点数就是带小数点的数。

String 不是八种基本类型之一,它是 Java 提供的文本类型;现在先把它当成“装一串文字的盒子”,第四单元再解释它和对象的关系。本节不需要键盘输入,所有值都直接写在源码里;下一节才用 Scanner 读终端输入。

SSH 服务器终端Java 源码程序交互输入输出示例(只读)复制 Java 源码不带文件名;复制命令不带 $ 提示符;输出和输入示例没有复制按钮。
这是教程网页,不是在线运行环境。Java 代码和 SSH 命令都要在你的服务器上执行;网页不会执行代码、不会连接服务器、也不会接收密码。

已完成 0 / 6 步

第 1 步:建 lesson02 目录,写第一版 VarDemo.java

先建本节自己的目录,并保护可能存在的旧文件。下面这套动作和上一节一样,只是目录名、文件名换了;请仍然逐行读,不要因为“见过”就跳过。

SSH 服务器终端bash
$ source ~/java-practice/env.sh
$ mkdir -p ~/java-practice/lesson02
$ cd ~/java-practice/lesson02
$ pwd
$ if [ -e VarDemo.java ]; then mv VarDemo.java "VarDemo.java.bak.$(date +%s)"; fi

最后一行先检查 VarDemo.java 是否存在;存在就改名成带时间戳的备份,不存在就什么也不做。这样你之前写的内容不会被静默覆盖。

nano 仍然单独占一个命令块,避免它吞掉后面的编译命令:

SSH 服务器终端bash
$ nano VarDemo.java

打开后粘贴下面整份源码,按 Ctrl+O、Enter、Ctrl+X 保存退出。

Java 源码VarDemo.java
public class VarDemo {
    public static void main(String[] args) {
        int age = 18;
        double price = 9.9;
        System.out.println(age);
        System.out.println(price);
    }
}

这份源码做了三件事:

  • int age = 18;:声明一个 int 类型的变量,名字叫 age,并赋值为 18。int 是“整数”类型,不能存小数。
  • double price = 9.9;:声明一个 double 类型的变量 price,赋值为 9.9。double 用来存带小数点的数。
  • System.out.println(age);:这里没有双引号,所以打印的是变量里保存的值,不是文字 age。

= 在这里是“赋值”:把右边的值放进左边的变量,不是数学里的“相等”。判断相等要用 ==,下一节会看到。变量名习惯用小写开头的驼峰写法,例如 age、totalPrice;名字区分大小写。

第 2 步:编译运行,看变量值

先编译,再运行。命令仍然是 javac -encoding UTF-8 文件名.java 和 java 类名。

SSH 服务器终端bash
$ javac -encoding UTF-8 VarDemo.java
$ java VarDemo

屏幕上应该出现:

输出示例(只读)output不可复制
18
9.9

println(age) 打印 18,println(price) 打印 9.9。注意输出里没有 age、price 这些变量名,变量名只是给人和编译器看的标签,不会自动变成输出内容。想让输出带说明文字,就要用本页第 6 步会细讲的字符串拼接,例如 "年龄:" + age。

如果 javac 报 cannot find symbol,先检查变量名拼写和大小写;如果报 incompatible types,先检查等号右边的值能不能放进左边声明的类型。

第 3 步:认识 char、boolean 和 String

现在把文件整份替换成下面这份,一次认识另外三种常用类型。仍然是打开同一个文件、整份替换,不是追加。

SSH 服务器终端bash
$ nano VarDemo.java
Java 源码VarDemo.java
public class VarDemo {
    public static void main(String[] args) {
        char grade = 'A';
        boolean passed = true;
        String name = "小安";
        System.out.println(grade);
        System.out.println(passed);
        System.out.println(name);
    }
}

保存退出后,编译运行:

SSH 服务器终端bash
$ javac -encoding UTF-8 VarDemo.java
$ java VarDemo
输出示例(只读)output不可复制
A
true
小安

三种类型逐个看:

  • char:单个字符,必须用单引号,例如 'A'、'中'。'A' 是一个字符;"A" 是一个长度为 1 的字符串,两者类型不同。
  • boolean:只有 true 和 false 两个值,不带引号。Java 的 boolean 不能用 0/1 代替;这一点和某些语言不同。
  • String:一串文字,必须用双引号,例如 "小安"。字符串里可以有空格、中文、标点,甚至空字符串 ""。

println 对这三种类型都能直接打印:char 原样打印字符,boolean 打印 true/false,String 打印引号里的内容(不打印引号本身)。

第 4 步:整数除法和小数除法不是一回事

这是初学者最常踩的坑之一。把文件整份替换成下面这份,先自己算一遍结果,再运行对照。

SSH 服务器终端bash
$ nano VarDemo.java
Java 源码VarDemo.java
public class VarDemo {
    public static void main(String[] args) {
        int total = 17;
        int people = 5;
        System.out.println("整数除法:" + (total / people));
        System.out.println("余数:" + (total % people));
        System.out.println("先转 double:" + ((double) total / people));
        double half = 7.0 / 2;
        System.out.println("小数除法:" + half);
    }
}
SSH 服务器终端bash
$ javac -encoding UTF-8 VarDemo.java
$ java VarDemo
输出示例(只读)output不可复制
整数除法:3
余数:2
先转 double:3.4
小数除法:3.5

规则:

  • int / int 做整数除法,结果只保留整数部分,小数部分被直接丢掉(不是四舍五入)。17 / 5 是 3,不是 3.4。
  • % 是取余,也叫求余数:17 % 5 是 2,因为 17 = 5 × 3 + 2。
  • 只要有一个操作数是 double,就做小数除法。(double) total / people 先把 total 临时转成 double,再除以 people,得到 3.4。
  • 7.0 / 2 里 7.0 是 double,所以结果是 3.5。写 7 / 2 则会得到 3。

这里第一次出现 "文字" + 数值 的写法,它的作用是把文字和数字接起来;本节第 6 步会专门讲 + 的两种含义,现在先照着看输出即可。

第 5 步:强制转换与 %,处理“取整”和“余数”

(int) 写在值前面叫强制转换(cast):明确告诉编译器“我知道会丢小数,还是把它转成整数”。把文件整份替换成:

SSH 服务器终端bash
$ nano VarDemo.java
Java 源码VarDemo.java
public class VarDemo {
    public static void main(String[] args) {
        double measured = 3.99;
        int cut = (int) measured;
        int apples = 23;
        int bags = 5;
        System.out.println("(int) 3.99 = " + cut);
        System.out.println("23 / 5 = " + (apples / bags));
        System.out.println("23 % 5 = " + (apples % bags));
        System.out.println("先加再除:" + ((apples + 1) / bags));
    }
}
SSH 服务器终端bash
$ javac -encoding UTF-8 VarDemo.java
$ java VarDemo
输出示例(只读)output不可复制
(int) 3.99 = 3
23 / 5 = 4
23 % 5 = 3
先加再除:4

要点:

  • (int) 3.99 得到 3,不是 4。强制转换是截断小数部分,向零取整,不做四舍五入。
  • 23 / 5 是 4,因为整数除法只留整数部分;23 % 5 是 3,因为 23 = 5 × 4 + 3。
  • (apples + 1) / bags 先算括号里的 24,再除以 5,仍是整数除法,结果是 4。括号改变的是运算顺序,不会自动把整数除法变成小数除法。
  • 如果想让 23 / 5 得到 4.6,要写成 (double) apples / bags 或 23.0 / 5。

% 不只是“余数”,后面学循环时会用它判断奇偶、做周期;现在只要会算 a % b,并知道 b 不能是 0。

第 6 步:用 + 拼接字符串,分清加法和拼接

+ 有两个身份:两边都是数字时做加法;只要有一边是 String,就做字符串拼接,把两边转成文字接起来。把文件整份替换成:

SSH 服务器终端bash
$ nano VarDemo.java
Java 源码VarDemo.java
public class VarDemo {
    public static void main(String[] args) {
        String name = "小安";
        int score = 92;
        System.out.println("姓名:" + name);
        System.out.println("分数:" + score);
        System.out.println("加分后:" + (score + 8));
        System.out.println("没有括号:" + score + 8);
        System.out.println("字母:" + 'A');
        System.out.println("字符加数字:" + ('A' + 1));
    }
}
SSH 服务器终端bash
$ javac -encoding UTF-8 VarDemo.java
$ java VarDemo
输出示例(只读)output不可复制
姓名:小安
分数:92
加分后:100
没有括号:928
字母:A
字符加数字:66

关键规则:

  • "姓名:" + name:左边是字符串,右边是字符串,直接拼接,得到 姓名:小安。
  • "分数:" + score:左边是字符串,右边是 int,score 被转成文字 92 再拼接,得到 分数:92。
  • "加分后:" + (score + 8):括号里的 score + 8 先做数字加法,得到 100,再拼接,输出 加分后:100。
  • "没有括号:" + score + 8:+ 从左到右算。先算 "没有括号:" + score,此时结果已经是字符串 没有括号:92;再 + 8 就变成拼接,得到 没有括号:928。
  • "字母:" + 'A':char 和字符串拼接,得到 字母:A。
  • ('A' + 1):括号里两边都是“能当数字算”的类型,char 会按 Unicode 编码参与加法;Unicode 是给字符编号的标准,'A' 的编号是 65,所以结果是 66。想得到文字 A1,要写成 "" + 'A' + 1。

+ 的优先级和从左到右的结合方向是考试和调试都常考的点。Java 的算术优先级和数学一样(先乘除后加减),同级从左到右。记不住时加括号:想先做算术,就把算术表达式括起来。

常见错误

  • **现象:incompatible types: possible lossy conversion from double to int。原因:把小数赋给 int,例如 int price = 9.9;。先检查什么:这个变量是否真的只存整数;要存小数就改成 double,确定要取整就用 (int) 9.9 并接受截断。**
  • **现象:cannot find symbol,指向一个变量名。原因:变量名拼错、大小写不一致,或使用发生在声明之前。先检查什么:逐字对照声明行和使用行;Java 要求先声明、再使用。**
  • **现象:unclosed character literal 或 unclosed string literal。原因:引号不配对,或该用双引号的地方用了单引号。先检查什么:char 用单引号且只放一个字符;String 用双引号;中文引号 “” 不是 Java 语法。**
  • **现象:int 除法得到 3,但你以为会得到 3.4。原因:两边都是 int,执行的是整数除法。先检查什么:看除号两边类型;需要小数就把其中一个转成 double,例如 (double) a / b。**
  • **现象:"总分:" + score + 8 输出 928,不是 100。原因:+ 从左到右,先拼接成字符串,后面的 8 也被拼接。先检查什么:给算术部分加括号 (score + 8)。**
  • **现象:variable age might not have been initialized。原因:只声明了变量,没有赋值就使用。先检查什么:声明时直接赋值,或在使用前补一行 age = 18;。**
  • **现象:';' expected。原因:上一行末尾漏了分号。先检查什么:看报错指出的行号和上一行末尾。**

练习

  1. 声明三个变量:String city = "杭州";、int days = 3;、double price = 12.5;,然后输出三行:目的地:杭州、天数:3、总价:37.5。先手算总价,再写程序核对。
  2. 不要运行,先判断下面两行分别输出什么,再写进程序验证:
    • System.out.println(1 + 2 + "3");
    • System.out.println("1" + 2 + 3);

先自己写、先写预测,再展开答案。

提示 提示

第 1 题的总价是 price * days;字符串和数字拼接时,想先算乘法就加括号。第 2 题盯着 + 的从左到右顺序:先遇到数字还是先遇到字符串,结果会不同。

参考答案 对答案

第 1 题的一份完整源码:

Java 源码TripDemo.java
public class TripDemo {
    public static void main(String[] args) {
        String city = "杭州";
        int days = 3;
        double price = 12.5;
        System.out.println("目的地:" + city);
        System.out.println("天数:" + days);
        System.out.println("总价:" + (price * days));
    }
}

运行输出:

输出示例(只读)output不可复制
目的地:杭州
天数:3
总价:37.5

第 2 题:1 + 2 + "3" 先算数字加法 1 + 2 得到 3,再和字符串 "3" 拼接,输出 33;"1" + 2 + 3 先拼接成 "12",再拼接 3,输出 123。两行都不是数学上的 6。

做到这里

做到这里今天可以停。你已经会用 int、double、char、boolean、String 声明变量,能读懂整数除法与小数除法的差别,会用 (int) 截断、用 % 取余,也能解释 + 什么时候是加法、什么时候是拼接。

本节还没有键盘输入,也没有 if、循环、数组或自定义方法。下一节 lesson03 才让程序用 Scanner 从终端读数据,并把本节的计算真正接到输入上。

来源 来源与改编说明(非官方)

主题参考:黑马程序员 Java 入门到起飞(BV17F411T7Ao,2022-04-27)P017–P025、P030–P032 的变量、数据类型、标识符、算术运算、类型转换、字符串和字符操作主题。本站为独立原创讲解,非官方站点/教材,未获授权,不逐字复刻视频或讲义;示例、错误清单与练习为原创补充。详见 source/SOURCE.md。

公开核对入口:

  • 课程页:https://www.bilibili.com/video/BV17F411T7Ao/
  • Oracle Java 教程 · 基本数据类型:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
  • Oracle Java 教程 · 运算符:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

说明:本站是个人学习整理,不是官方教材;不包含原课程的书本、视频或受版权保护的整本内容。原课程与商标归其权利人。