JavaSE 基础语法 - 数据类型与变量
一、什么是变量为什么需要数据类型1.1 变量是什么简单理解变量就是用来存储数据的 “盒子” 这个盒子有自己的 “名字”变量名、“规格”数据类型里面装的 “东西”数据可以随时替换。在程序中所有需要临时保存的数据比如用户的年龄、姓名、考试成绩、商品价格、登录状态等都需要存放在变量中否则程序无法对这些数据进行运算和处理。1.2 什么是数据类型数据类型本质上就是给变量规定 “能存什么数据”“占多大内存空间” 的 “规则”。Java 是一门 强类型语言这意味着每个变量在使用前必须先明确指定它的数据类型不能直接写 “变量名 值”否则程序会报错。比如要存 “年龄”18、20、30就用 “整数类型”不能存小数要存 “商品价格”19.9、99.9就用 “小数类型”要存 “姓名”张三、李四就用 “字符串类型”要存 “登录状态”登录 / 未登录就用 “布尔类型”。二、Java 数据类型分类2.1 基本数据类型基本数据类型是 Java 自带的、最基础、最简单的类型直接存储数据本身比如存 18就直接把 18 存在内存中不需要额外的内存开销效率高。8 种基本数据类型的详细信息如下表所示。数据类型含义占用字节数取值范围byte字节型1-128 ~ 127short短整型2-32768 ~ 32767int整型4-2147483648 ~ 2147483647long长整型8-9223372036854775808 ~ 9223372036854775807float单精度浮点数4约 ±3.4×10³⁸double双精度浮点数8约 ±1.8×10³⁰⁸char字符型20 ~ 65535boolean布尔型没有明确规定只有两个值true真、false假不论是在16位系统还是32位系统int都占用4个字节long都占8个字节整形和浮点型都是带有符号的整型默认为int型浮点型默认为double字符串属于引用类型该中类型后序介绍。这8 种基本数据类型中最常用的 5 个int整数、double小数、char单个字符、boolean判断、String字符串注意String 不是基本类型2.2 引用数据类型除了 8 种基本数据类型Java 中其他所有类型都属于引用数据类型。引用数据类型不直接存储数据本身而是存储 “数据的地址”相当于存了一个 “指针”指向数据实际存储的位置就像我们存朋友的地址通过地址就能找到朋友而不是直接把朋友存在变量里。常见的引用数据类型String字符串类型存一串文字如 “张三”“Java 零基础”自定义类比如我们后续会学的 Student学生类、Teacher教师类数组存一组相同类型的数据如一组成绩、一组姓名接口后续章节详解用于定义行为规范。注意很多新手会把 String 当成基本数据类型记住String 是引用数据类型不是基本数据类型它的使用方式和基本类型类似但本质不同。三、8 大基本数据类型详解3.1 整数类型整数类型专门用来存储 “没有小数部分” 的数字分为 4 种核心区别是 “占用内存大小” 和 “取值范围”日常开发中仅需重点掌握 int 和 long。byte字节整数byte在任何系统下都占1个字节字节的包装类型为Byte后续章节会介绍。bytenum100;// 合法在 -128~127 范围内// byte num2 130; // 报错超出 byte 取值范围short短整数short在任何系统下都占2个字节使用时注意不要超过范围(一般使用比较少)short的包装类型为Short后续章节会介绍。shortage20;// 合法// short age2 40000; // 报错超出 short 取值范围int整数最常用int不论在何种系统下都是4个字节推荐使用方式一定义如果没有合适的初始值可以设置为0在给变量设置初始值时值不能超过int的表示范围否则会导致溢出变量在使用之前必须要赋初值否则编译报错int的包装类型为 Integer后续章节会介绍。intage18;// 存年龄intscore98;// 存整数分数intcount100;// 存数量// int phone 13800138000; // 报错手机号超出 int 取值范围需用 long注意在 Java 中, int 除以 int 的值仍然是 int(会直接舍弃小数部分)。如果想得到 0.5, 需要使用 double 类型计算。long长整数长整型不论在那个系统下都占8个字节长整型变量的初始值后加L或者l推荐加Llong的包装类型为Long后续章节会介绍。longphone13800138000L;// 存手机号必须加 Llongtime1690000000000L;// 存时间戳必须加 Llongnum2200000000L;// 超过 21 亿必须用 long 且加 L提问byte、short、int、long都可以定义整形变量为什么要给出4中不同类型呢原因就在于为了应对不同数据范围需求减少内存占用根据实际存储数值大小选用对应类型既防止数值溢出又避免资源浪费。就比如说你去寄一个快递小的东西用小盒子装大的东西要大盒子装。3.2 浮点类型浮点类型专门用来存储 “有小数部分” 的数字分为 float 和 double核心区别是 “精度” 和 “内存占用”日常开发重点掌握 double。float单精度浮点数float在任何系统下都占4个字节float的包装类型为Float。float类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差因此浮点数是个近似值并不是精确值。floatheight1.75F;// 存身高必须加 Ffloatweight65.5F;// 存体重必须加 F// float price 19.9; // 报错19.9 默认是 double 类型不能直接赋值给 floatdouble双精度浮点数最常用double在任何系统下都占8个字节浮点数与整数在内存中的存储方式不同不能单纯使用 的形式来计算double的包装类型为Double后续章节会介绍。double 类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差因此浮点数是个近似值并不是精确值。doubleprice19.9;// 存商品价格默认 doubledoublescore95.5;// 存小数分数doublepi3.1415926535;// 存高精度小数适合用 double注意如果需要极高精度如金融计算避免误差不能用 float 和 double需使用 Java 提供的 BigDecimal 类后续进阶章节详解。3.3 字符类型charchar在任何系统下都占2个字节Java 中使用 单引号 单个字母 的形式表示字符字面值char的包装类型为Character后续章节会介绍计算机中的字符本质上是一个整数. 在 C 语言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表示字符. 因此一个字符占用两个字节, 表示的字符种类更多, 包括中文。charc1A;// 英文字母合法charc29;// 数字合法charc3中;// 中文合法Java 原生支持中文字符charc4!;// 符号合法// char c5 A; // 报错用了双引号是字符串不是单个字符// char c6 AB; // 报错存了两个字符超出 char 范围3.4 布尔类型 booleanJava虚拟机规范中并没有明确规定boolean占几个字节也没有专门用来处理boolean的字节码指令boolean 类型的变量只有两种取值, true 表示真, false 表示假Java 的 boolean 类型和 int 不能相互转换, 不存在 1 表示 true, 0 表示 false 这样的用法boolean的包装类型为Boolean后续章节会介绍。booleanisStudenttrue;// 登录状态已登录booleanisPassfalse;// 考试结果未通过booleanhasMoneytrue;// 判断有钱// boolean isOk 1; // 报错不能用数字代替 true/false四、变量的定义与使用4.1 变量的定义格式变量的定义有固定格式缺一不可格式如下数据类型 变量名初始值;数据类型指定变量能存什么类型的数据如 int、double、String变量名给变量起的 “名字”必须遵守标识符命名规则初始值变量第一次存储的数据可以先不赋值但后续使用前必须赋值。三种定义方式声明并赋值最常用直接定义变量同时给变量赋值定义后可以直接使用。intage18;// 声明 int 类型变量 age赋值为 18doubleprice19.9;// 声明 double 类型变量 price赋值为 19.9Stringname张三;// 声明 String 类型变量 name赋值为 张三先声明后赋值适合变量值不确定的场景先定义变量只指定类型和名字后续根据需求赋值但使用前必须赋值否则报错。intscore;// 先声明 int 类型变量 score不赋值score95;// 后续赋值为 95赋值后才能使用System.out.println(score);// 合法输出 95// int num;// System.out.println(num); // 报错变量未赋值不能使用一次性声明多个同类型变量简化写法慎用可以一次性声明多个同类型的变量用逗号分隔适合变量类型相同的场景但不推荐新手使用容易混淆。inta10,b20,c30;// 一次性声明 3 个 int 类型变量分别赋值// 等价于// int a 10;// int b 20;// int c 30;4.2 变量的使用规则规则 1先声明再使用必须遵守变量必须先定义声明才能使用不能直接使用未声明的变量。// System.out.println(age); // 报错age 未声明intage18;System.out.println(age);// 合法输出 18规则 2先赋值再使用必须遵守即使声明了变量如果没有赋值也不能使用局部变量后续详解。intage;// System.out.println(age); // 报错age 已声明但未赋值age18;System.out.println(age);// 合法规则 3同一个作用域内变量名不能重复必须遵守“作用域” 简单理解变量能生效的范围比如一个方法内、一个代码块内在同一个范围内不能有两个名字相同的变量。intage18;// int age 20; // 报错同一个作用域内age 已经声明过规则 4变量只在自己的作用域内有效了解后续详解变量的作用域决定了变量能在哪些代码中使用超出作用域后变量就会被 “销毁”无法再使用。if(true){intnum10;// 变量 num 的作用域是这个 if 代码块内System.out.println(num);// 合法在作用域内}// System.out.println(num); // 报错超出作用域num 已被销毁五、常量final 关键字5.1 什么是常量常量和变量相比一旦赋值就不能再修改的量相当于一个 “固定的盒子”里面的东西不能替换。生活中的例子圆周率 π3.14159…、一年的月份数12、身份证号一旦确定不会改变这些都属于常量。程序中的常量通常用于存储 “固定不变的值”比如圆周率、最大值、固定的配置信息等目的是1. 避免重复写相同的值2.防止误修改。5.2 常量的定义格式常量的定义需要用 final 关键字修饰格式如下final数据类型 常量名初始值;final关键字含义是 “最终的”修饰后变量的值不能再修改数据类型和变量一样指定常量的类型如 int、double常量名必须遵守标识符命名规则且有特殊规范初始值常量必须在声明时就赋值不能先声明后赋值和变量不同。注意常量声明时必须赋值且赋值后不能再修改否则报错。代码示例重点掌握finaldoublePI3.14159;// 圆周率固定不变finalintMAX_SCORE100;// 满分固定不变finalStringSCHOOL_NAMEXX中学;// 学校名称固定不变// PI 3.14; // 报错常量赋值后不能修改// final int MIN_SCORE; // 报错常量声明时必须赋值5.3 常量的命名规范常量的命名有严格的行业规范新手必须遵守便于团队协作和代码可读性所有字母 全部大写多个单词之间用 下划线 _ 分隔不能用关键字、中文、特殊符号除了下划线。// 正确示例PI、MAX_SCORE、SCHOOL_NAME、MIN_AGE// 错误示例pi小写、maxScore小驼峰、学校名称中文、max-score用了减号六、标识符命名规则标识符简单来说就是 “程序员自定义的名字”包括类名、变量名、方法名、常量名、包装类名等所有自定义的名字都必须遵守以下规则。6.1 硬性规则这 4 条规则是 Java 语法强制要求的违反任何一条程序都会编译报错新手一定要逐个核对规则 1组成字符只能是 4 种标识符只能由 英文字母A-Z、a-z、阿拉伯数字0-9、下划线_、美元符号$ 组成不能有其他字符如中文、减号、空格、 等。intstudentName18;// 合法字母下划线int$salary5000;// 合法美元符号int_age220;// 合法下划线字母数字// int 学生年龄 18; // 报错包含中文// int a-b 10; // 报错包含减号// int a b 20; // 报错包含空格规则 2不能以数字开头标识符可以包含数字但不能以数字作为开头否则报错。intage118;// 合法数字在后面// int 1age 18; // 报错以数字开头规则 3不能是 Java 关键字Java 中的关键字如 public、class、int、final是预留的特殊单词有固定含义不能作为标识符使用。// int class 10; // 报错class 是关键字// int public 20; // 报错public 是关键字规则 4严格区分大小写Java 是大小写敏感的语言标识符的大小写不同代表不同的名字。intage18;intAge20;// 这是两个不同的变量不会报错但是不推荐容易混淆6.2 软性规范这几条不是语法强制要求的但属于行业通用规范新手从一开始就要养成习惯否则写的代码会被认为 “不规范”影响团队协作标识符类型命名规范示例类名大驼峰命名法首字母大写后续每个单词首字母也大写Student、HelloWorld、Integer变量名小驼峰命名法首字母小写后续每个单词首字母大写studentName、userAge、price方法名小驼峰命名法和变量名一致getName()、setAge()、calculateScore()常量名全大写单词之间用下划线分隔PI、MAX_SCORE、SCHOOL_NAME提醒标识符的名字要 “见名知意”比如用 age 表示年龄用 price 表示价格不要用 a、b、c 这种无意义的名字便于后续自己阅读和他人理解。七、数据类型转换在程序中我们经常需要将一种数据类型转换成另一种数据类型比如把 int 转换成 double把 double 转换成 intJava 中数据类型转换分为两种自动类型转换、强制类型转换新手必须分清二者的区别和使用场景。7.1 自动类型转换隐式转换无需手动操作自动类型转换即代码不需要经过任何处理在代码编译时编译器会自动进行处理。特点数据范围小的转为数据范围大的时会自动进行。自动类型转换的顺序从左到右范围从小到大// byte → short → int → long → float → doublechar 类型比较特殊会自动转换成 int因为 char 存储的是 Unicode 编码本质是整数小范围 → 大范围自动转换大范围 → 小范围不能自动转换必须强制转换。// 1. int → double小范围 → 大范围自动转换inta10;doubleba;// 自动转换b 的值是 10.0System.out.println(b);// 输出 10.0// 2. byte → int小范围 → 大范围自动转换bytec5;intdc;// 自动转换d 的值是 5// 3. char → int自动转换char 存储的是 Unicode 编码chareA;intfe;// A 的 Unicode 编码是 65所以 f 的值是 65System.out.println(f);// 输出 65// 4. int → long小范围 → 大范围自动转换intg100;longhg;// 自动转换h 的值是 100L7.2 强制类型转换显式转换必须手动操作强制类型转换当进行操作时代码需要经过一定的格式处理不能自动完成。特点数据范围大的到数据范围小的。// (目标数据类型) 要转换的变量/值;目标数据类型我们想要转换成的类型如 int、byte括号必须包裹目标数据类型不能省略要转换的变量 / 值需要转换的大范围数据。// 1. double → int大范围 → 小范围强制转换doublenum3.99;inti(int)num;// 强制转换把 double 转换成 intSystem.out.println(i);// 输出 3注意直接截断小数部分不是四舍五入// 2. long → int大范围 → 小范围强制转换longphone13800138000L;intphoneInt(int)phone;// 强制转换但会造成数据溢出System.out.println(phoneInt);// 输出负数溢出后的值无意义// 3. int → byte大范围 → 小范围强制转换intj130;bytek(byte)j;// 强制转换超出 byte 取值范围溢出System.out.println(k);// 输出 -126溢出后的值无意义强制转换的两个核心问题精度丢失针对浮点型转整数型当把 double、float 等浮点类型强制转换成 int、long 等整数类型时会 直接截断小数部分不会进行四舍五入导致精度丢失。doublenum13.99;inti1(int)num1;// i1 3不是 4doublenum23.14;inti2(int)num2;// i2 3不是 3数据溢出针对整数型之间的转换当把大范围的整数如 long强制转换成小范围的整数如 int、byte时如果大范围的值超出了小范围的取值范围会导致 数据溢出转换后的值变成无意义的负数或乱码这是新手最容易忽略的坑。// long 类型的 2200000000超出 int 的取值范围±21 亿longnum2200000000L;inti(int)num;// 强制转换数据溢出System.out.println(i);// 输出 -2094967296无意义错误值7.3 类型提升不同类型的数据之间相互运算时数据类型小的会被提升到数据类型大的。int与long之间int会被提升为longinta10;longb20;intcab;// 编译出错: a b》int long-- long long 赋值给int时会丢失数据longdab;// 编译成功a bint long---long long 赋值给longbyte与byte的运算bytea10;byteb20;bytecab;System.out.println(c);// 编译报错Test.java:5:错误:不兼容的类型:从int转换到byte可能会有损失bytecab;^结论:byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a b 会先将 a和 b 都提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误。由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short这种低于 4 个字节的类型, 会先提升成 int, 再参与计算。正确的写法bytea10;byteb20;bytec(byte)(ab);System.out.println(c);提升1.不同类型的数据混合运算, 范围小的会提升成范围大的2.对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算。八、String 字符串引用类型String 是 Java 中最常用的引用数据类型专门用来存储 “一串字符”如姓名、地址、提示信息等虽然它是引用类型但使用方式和基本类型类似。8.1 String 的定义String 类型的变量定义时必须用 双引号 “” 包裹字符串内容不能用单引号单引号是 char 类型的标识。代码示例Stringname张三;// 合法双引号包裹Stringaddress北京市海淀区;// 合法多个字符StringtipHello Java!;// 合法包含字母和符号// String gender 男; // 报错单引号是 char 类型不能用于 String// String empty null; // 不推荐赋值为 null 容易报错新手暂时避免// String是不可变的// 比如说Stringsabc;ssdef;// 结果并不是 abcdef// 实际上是旧对象不会修改而是会重新创建一个新的String对象8.2 字符串的拼接String 类型的核心用法之一是 “拼接”用 号 实现拼接规则如下两个 String 类型拼接结果还是 String 类型String 类型 基本类型int、double、char 等结果是 String 类型基本类型会自动转换成 String基本类型 基本类型 String 类型从左到右运算先算基本类型的运算再和 String 拼接。代码示例// 1. 两个 String 拼接StringaHello;Stringb World;Stringcab;System.out.println(c);// 输出 Hello World// 2. String intStringd年龄;intage18;Stringedage;System.out.println(e);// 输出 年龄18// 3. String doubleStringf价格;doubleprice19.9;Stringgfprice;System.out.println(g);// 输出 价格19.9// 4. 基本类型 基本类型 String易错点intnum110;intnum220;Stringhnum1num2元;// 先算 102030再和 元 拼接System.out.println(h);// 输出 30元Stringi总价num1num2;// 先拼接 总价10再拼接 20System.out.println(i);// 输出 总价1020不是 总价30注意注意拼接顺序基本类型和 String 拼接时谁在前面决定了运算结果比如 1020“元” 和 “元”1020 的结果完全不同。8.3 String 的常用基础方法String 提供了很多实用方法新手先掌握这 3 个最常用的后续章节会详解更多// 1. 获取字符串长度length()StringstrHello Java;intlengthstr.length();System.out.println(length);// 输出 10包含空格// 2. 判断字符串是否为空isEmpty()Stringstr2;booleanisEmptystr2.isEmpty();System.out.println(isEmpty);// 输出 true空字符串// 3. 字符串转小写/大写toLowerCase()/toUpperCase()Stringstr3Hello Java;Stringlowerstr3.toLowerCase();// 转小写Stringupperstr3.toUpperCase();// 转大写System.out.println(lower);// 输出 hello javaSystem.out.println(upper);// 输出 HELLO JAVA