7. 【Java】变量与数据类型 摘要本文讲解了Java中变量与数据类型这一核心基础概念。系统介绍了八种基本数据类型byte、short、int、long、float、double、char、boolean和引用类型的区别与用法详细说明了变量的声明、初始化、作用域规则以及类型转换机制并提供了完整的代码示例帮助读者巩固理解。关键词Java变量, 数据类型, 基本类型, 引用类型, 类型转换在上一篇里你亲手写了一个小项目。虽然它很朴素只有几十行代码但你已经体验到了“程序在跟人打交道”的感觉你问用户问题用户回答然后你根据回答做出回应。但你有没有想过那些用户输入的名字“张三”、年龄“25”、城市“成都”……它们在程序里到底是怎么存放的如果你在程序里写int age 25;那个25在计算机的内存里是什么样子的今天我们就来解答这些问题。我们要聊的是 Java 世界里最基础、也最重要的概念变量和数据类型。1. 先打个比方变量就像“贴了标签的盒子”想象你有一个收纳箱你需要把不同种类的物品放进去。为了以后方便找到你会在箱子上贴个标签写上“文具”或“衣物”。如果你放进去的是铅笔你当然不会在箱子上贴“食物”。在程序里变量就是一个“贴了标签的盒子”盒子的名字就是变量名比如age、name。盒子里装的东西就是变量的值比如25、张三。盒子的大小和用途由数据类型决定——有些盒子只能装整数有些盒子只能装文字不能混装。Java 是一门强类型语言意思是每个变量在声明时就必须明确它的数据类型而且一旦确定它就只能存储该类型的数据。这听起来有点严格但正是这种严格保证了程序的安全和稳定——你不会不小心把一个字符串塞进一个整数变量里从而引发难以察觉的 bug。2. 数据类型大家族一八种基本数据类型Java 的数据类型分为两大类基本类型primitive type和引用类型reference type。我们先讲基本类型。它们是 Java 语言内置的、最基础的原子类型一共只有 8 种按用途可以分为四组分组类型字节数取值范围简要默认值整数byte1-128 ~ 1270整数short2-32768 ~ 327670整数int4约 ±21 亿0整数long8约 ±9.22×10¹⁸0L小数float4约 ±3.4×10³⁸0.0f小数double8约 ±1.8×10³⁰⁸0.0d字符char20 ~ 65535Unicode‘\u0000’布尔boolean1虚拟true或falsefalse别被这个表格吓到。你不需要死记硬背每个字节数只需要知道以下几点① 整数byte、short、int、long你平时写整数默认就是int类型。比如int age 25;。如果数字特别大超过 21 亿就要用long并在数字后面加L或l小写 L但容易跟 1 混淆建议大写。例如long worldPopulation 8000000000L;。byte和short一般用在节省内存的场景比如大数组初学阶段用得不多但你得知道它们存在。② 小数float 和 double你平时写小数默认是double因为它精度更高。比如double pi 3.14159;。如果非要使用float数字后面要加F或f例如float price 9.99f;。关于小数的精度问题比如 0.1 0.2 不等于 0.3我们以后在进阶篇会细说现在先记住涉及金钱计算不要用 float 或 double要用BigDecimal后面会学。③ 字符charchar用来表示单个字符用单引号括起来。例如char grade A;、char chinese 好;。Java 使用 Unicode 编码所以char可以表示中文字符也可以表示表情符号但表情符号需要两个char组合以后再说。另外char底层其实是一个无符号的 16 位整数所以它可以直接和int互相赋值比如int num A;会得到数字 65ASCII码。这个特性在以后处理字符时非常有用。④ 布尔boolean只有两个值true和false。用在条件判断中比如“是否成年”、“是否登录成功”。3. 数据类型大家族二引用类型 —— 对象的“遥控器”除了八种基本类型其他所有类型都是引用类型reference type。引用类型的变量不直接存储数据本身而是存储数据在内存中的“地址”。打个比方基本类型的盒子里直接装着数据本身比如数字 25而引用类型的盒子里装的是一张写着电视机位置的小纸条内存地址你拿着这张纸条就像遥控器就能找到那台真正的电视机真正的对象。最常见的引用类型包括类比如我们之前用的String、Scanner、以及我们自己定义的Student。接口interface数组array在代码里引用类型的变量声明和使用方式跟基本类型很像但它们的行为有本质区别。我们以后会深入讲现在你先记住用new关键字创建出来的东西几乎都是引用类型。4. 变量的声明、初始化与作用域① 声明Declaration声明变量就是告诉编译器“我要一个盒子名字叫 xxx类型是 xxx。”intage;// 声明了一个 int 类型的变量 ageStringname;// 声明了一个 String 类型的变量 name引用类型② 初始化Initialization初始化就是第一次给变量赋值。变量必须初始化之后才能使用否则编译会报错。初学者经常遇到这个报错如果你的 IDE 旁边出现红色波浪线并提示variable might not have been initialized变量可能尚未初始化就是因为这个原因。age25;// 赋值name张三;// 赋值也可以声明和初始化写在一起intage25;Stringname张三;③ 作用域Scope变量的“存活范围”由它所在的花括号{}决定。一个变量从声明的位置开始到它所在的代码块结束为止都是有效的。超出这个范围变量就“消失”了。publicclassDemo{// 成员变量在整个类里都有效我们以后细讲privateintclassVar;publicvoidtest(){intlocalVar10;// 局部变量只在 test 方法内有效if(localVar5){intinnerVar20;// 只在 if 代码块内有效System.out.println(innerVar);}// System.out.println(innerVar); // 错误innerVar 已经不存在了}} 初学者最常见的错误之一就是在作用域外使用变量。IDEA 会给你红色波浪线提示记得留意。5. 类型转换 —— 数据之间的“翻译官”有时候我们需要把一种类型的数据转换成另一种。Java 的类型转换分为两种① 自动类型转换隐式转换当小范围类型赋值给大范围类型时Java 会自动帮你转不需要额外操作。范围从小到大排序byte short int long float double。这里有个“反直觉”的地方虽然long占 8 字节float只占 4 字节但float表示的范围却更大所以long可以自动转float但有精度损失。为什么呢因为浮点数在底层是用科学计数法存储的虽然 float 只有 4 个字节但它能表示的数字范围远大于 8 字节的 long代价是会牺牲一些精度大数字的末几位会被舍去。intnum100;longbigNumnum;// 自动转换没问题doublepinum;// 自动转换100.0② 强制类型转换显式转换当大范围类型赋值给小范围类型时必须强制转换因为可能会丢失数据。语法是在值前面加上(目标类型)。doubleprice9.99;intintPrice(int)price;// 强制转换结果为 9小数部分被截断System.out.println(intPrice);// 输出 9强制转换要小心因为它可能溢出或丢失精度。比如把一个很大的long强制转成int结果可能会变成一个完全不同的负数因为高位被截断。③ 字符串与数字的转换这是我们上一篇实际用到过的。Scanner读进来的都是字符串我们需要把它们转成数字字符串 → 整数Integer.parseInt(123)字符串 → 小数Double.parseDouble(3.14)数字 → 字符串可以用String.valueOf(123)或者直接用 123字符串拼接。6. 用实际代码感受一下我们写一个简单的小程序把今天讲的概念串起来packagecom.example.demo;publicclassDataTypeDemo{publicstaticvoidmain(String[]args){// 1. 基本类型声明与初始化byteb100;shorts20000;inti1234567890;longl9876543210L;// 注意 Lfloatf3.14f;// 注意 fdoubled2.71828;charcA;booleanbooltrue;// 2. 输出看看System.out.println(byte: b);System.out.println(short: s);System.out.println(int: i);System.out.println(long: l);System.out.println(float: f);System.out.println(double: d);System.out.println(char: c);System.out.println(boolean: bool);// 3. 引用类型StringStringname小明;System.out.println(名字name);// 4. 类型转换演示intnum256;bytebyteNum(byte)num;// 强制转换256 超出 byte 范围结果会溢出// 输出 0二进制高位被截断256的二进制是 1 0000 0000byte只取后8位即 0000 0000System.out.println(256 强转成 byte 后byteNum);doublepi3.14159;intintPi(int)pi;// 强制转换截断小数System.out.println(3.14159 强转成 int 后intPi);// 输出 3// 5. 字符串转数字StringageStr25;intageInteger.parseInt(ageStr);System.out.println(年龄age);// 6. 数字转字符串intscore95;StringscoreStrString.valueOf(score);System.out.println(成绩字符串scoreStr);}}你可以运行一下观察输出结果特别留意256强制转成byte后变成了0——这就是“数据溢出”的例子。7. 变量命名的最佳实践最后再强调一下命名变量名要做到“见名知意”。不要用a、b、c而要用age、studentName、totalScore。使用驼峰命名法camelCase第一个单词小写后续单词首字母大写。比如myAge、isStudent。常量用final修饰全部大写下划线分隔final double PI 3.14159;。今天的总结今天我们打开了 Java 数据世界的大门。你知道了Java 有八种基本数据类型byte、short、int、long、float、double、char、boolean。其他类型都是引用类型比如String、Scanner和我们自定义的类。变量需要先声明再初始化才能使用并且有作用域限制。类型转换分自动和强制两种强制转换要小心数据丢失。字符串和数字之间可以互相转换。这些概念看似简单却是你以后写任何 Java 程序的基石。从今天开始每当你声明一个变量都可以想一想它的类型是什么它会在哪里被使用它的值可能是什么范围动手试试把上面的DataTypeDemo代码敲一遍运行并观察结果。然后尝试把byte byteNum (byte) num;中的num改成 300、500看看输出分别是什么想想为什么。声明一个float变量赋值为3.14不加f看看编译器会不会报错体会一下为什么。写一段代码声明一个int变量maxInt Integer.MAX_VALUE;然后打印它再加 1打印结果看看发生了什么这就是整数溢出的经典例子。下篇文章我们会聊常量和字面量——那些“不变”的值以及final关键字、枚举的初步认识。我们继续一步步往前走。我们下一篇见。 获取本系列示例代码请访问 GitCode。