你有思考过编程语言为什么要有「数据类型」吗?
面试官其实是想让你告诉他:小讯同学是谁?她出生在哪儿?
目录
1、困扰小讯同学的一串神秘数字
2、场景技术实现
2.1 最终效果图
2.2 奉上源码
2.2.1 神秘数字信息
2.2.2 破解神秘数字工具
3、回头看技术
3.1 Java为什么要有基础类型
3.2 Java基础类型存储在哪儿
1、困扰小讯同学的一串神秘数字
500年前,孙大圣对自己的身世很不解:我是谁?我来自哪儿?
500年后,有一个人也有了同样的困惑,这个困惑却源于一串神秘的数字。
今天主角是我们的小讯同学。
小讯同学上小学的时候很爱学习,对新鲜事物充满了好奇。不过很多事情不是她这个年龄能想明白的,那其中就有一个神秘的问题困扰了她很久。
在很小的时候,小讯因为感冒发烧成了儿童医院的常客。不过令她很好奇的是:每次医生都要小讯的爸爸提供小讯的个人信息——名字、性别、年龄、出生日期、出生地点、体重等信息。更为奇怪的是, 医生还要了一串很奇怪的数字~。
但对于当时的小讯来说,她根本看不懂这串数字,但每次好奇心总是会让她去思考一个问题:这串数字究竟代表什么?
随着小讯同学渐渐长大,她发现很多场合都会用到这串数字,比如上学、坐飞机、乘高铁、甚至进游乐场。 小讯同学隐约感到了这串数字和自己一定有着一种密不可分的关系,但究竟是什么密不可分的关系呢?
直到小讯同学碰到了她的第一个会Java编程的计算机王老师,才算彻底让她把这个困惑搞明白。
原来这串数字就是我啊<~..~>
接下来我们看看王老师是如何帮助小讯解决困惑的。
2、场景技术实现
王老师把这串神秘的数字进行了一一拆解:终于让这串数字真相大白。
2.1 最终效果图
2.2 奉上源码
2.2.1 神秘数字信息
import java.io.Serializable;
public class IdCardNoInfo implements Serializable {
private Integer provinceCode; //省编码
private Integer cityCode;// 市编码
private Integer countryCode; // 县代码
private String birthdayDate;// 出生日期
private Long residentNumber; //同一地址码所标示的区域范围内,对同年同月同日生的居民编订的顺序码
private Integer sex; //性别
private Integer validCode; //校验码
public Integer getProvinceCode() {
return provinceCode;
}
public void setProvinceCode(Integer provinceCode) {
this.provinceCode = provinceCode;
}
public Integer getCityCode() {
return cityCode;
}
public void setCityCode(Integer cityCode) {
this.cityCode = cityCode;
}
public Integer getCountryCode() {
return countryCode;
}
public void setCountryCode(Integer countryCode) {
this.countryCode = countryCode;
}
public String getBirthdayDate() {
return birthdayDate;
}
public void setBirthdayDate(String birthdayDate) {
this.birthdayDate = birthdayDate;
}
public Long getResidentNumber() {
return residentNumber;
}
public void setResidentNumber(Long residentNumber) {
this.residentNumber = residentNumber;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getValidCode() {
return validCode;
}
public void setValidCode(Integer validCode) {
this.validCode = validCode;
}
}
2.2.2 破解神秘数字工具
package com.my.plugins.order.day02;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Random;
public class MyComeWhereUtil {
public static void main(String[] args) {
// 请输入您的身份证号码,让我猜猜你来自哪儿?你是谁?
for (int i = 0; i < 20; i++) {
String buildIdCard = buildIdCard();
IdCardNoInfo info = build(buildIdCard);
String buildArea = buildArea(info);
String buildAge = buildAge(info.getBirthdayDate());
Object buildSex = buildSex(info.getSex());
if(null != buildArea && !"".equals(buildArea.trim())) {
System.out.println(String.format("欢迎[%s]来自美丽里的[%s][%s]后[%s]~~",
buildIdCard, buildArea, buildAge, buildSex));
}
}
}
public static IdCardNoInfo build(String code) {
IdCardNoInfo info = new IdCardNoInfo();
info.setProvinceCode(Integer.parseInt(code.substring(0, 2)));
info.setCityCode(Integer.parseInt(code.substring(0, 4)));
info.setCountryCode(Integer.parseInt(code.substring(0, 6)));
info.setBirthdayDate(code.substring(6, 14));
info.setSex(Integer.parseInt(code.substring(14, 15)));
info.setResidentNumber(Long.parseLong(code.substring(15, 17)));
info.setValidCode(Integer.parseInt(code.substring(17)));
return info;
}
public static String buildArea(IdCardNoInfo info) {
StringBuilder sb = new StringBuilder();
URL resource = MyComeWhereUtil.class.getClassLoader().getResource("area_code.txt");
try {
FileInputStream inputStream = new FileInputStream(resource.getFile());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str = null;
int count = 0;
while (true) {
if ((str = bufferedReader.readLine()) == null) break;
String[] strAry = str.split(";");
String code = strAry[0];
String name = strAry[1];
if (code.equals(format(info.getCountryCode()))) {
sb.append(name);
}
if (code.equals(format(info.getCityCode()))) {
sb.append(name);
}
if (code.equals(format(info.getProvinceCode()))) {
sb.append(name);
}
}
inputStream.close();
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private static Object buildSex(Integer sex) {
return sex % 2 == 0 ? "美女" : "帅哥";
}
private static String buildAge(String birthdayDate) {
Integer preYeay = Integer.parseInt(birthdayDate.substring(2, 3));
Integer lastYeay = Integer.parseInt(birthdayDate.substring(3, 4));
if (lastYeay >= 5) {
return preYeay + "5";
} else {
return preYeay + "0";
}
}
public static String format(Integer num) {
return zeroFormat(num, 6, Boolean.FALSE);
}
public static String zeroFormat(Integer num, int len, boolean prev) {
int l = num.toString().length();
StringBuffer sb = new StringBuffer();
if (!prev)
sb.append(num);//后补
for (int i = 0; i < len - l; i++)
sb.append("0");
if (prev)
sb.append(num);//前补
return sb.toString();
}
private static String buildIdCard() {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 3; i++) {
Random r = new Random();
sb.append(r.nextInt(300001) + 100000);//随机生产6位数
}
return sb.toString();
}
}
area_code.txt 由于数据量比较大,私信博主后发给大家~
import java.io.Serializable;
public class IdCardNoInfo implements Serializable {
private Integer provinceCode; //省编码
private Integer cityCode;// 市编码
private Integer countryCode; // 县代码
private String birthdayDate;// 出生日期
private Long residentNumber; //同一地址码所标示的区域范围内,对同年同月同日生的居民编订的顺序码
private Integer sex; //性别
private Integer validCode; //校验码
public Integer getProvinceCode() {
return provinceCode;
}
public void setProvinceCode(Integer provinceCode) {
this.provinceCode = provinceCode;
}
public Integer getCityCode() {
return cityCode;
}
public void setCityCode(Integer cityCode) {
this.cityCode = cityCode;
}
public Integer getCountryCode() {
return countryCode;
}
public void setCountryCode(Integer countryCode) {
this.countryCode = countryCode;
}
public String getBirthdayDate() {
return birthdayDate;
}
public void setBirthdayDate(String birthdayDate) {
this.birthdayDate = birthdayDate;
}
public Long getResidentNumber() {
return residentNumber;
}
public void setResidentNumber(Long residentNumber) {
this.residentNumber = residentNumber;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getValidCode() {
return validCode;
}
public void setValidCode(Integer validCode) {
this.validCode = validCode;
}
}
2.2.2 破解神秘数字工具
package com.my.plugins.order.day02;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Random;
public class MyComeWhereUtil {
public static void main(String[] args) {
// 请输入您的身份证号码,让我猜猜你来自哪儿?你是谁?
for (int i = 0; i < 20; i++) {
String buildIdCard = buildIdCard();
IdCardNoInfo info = build(buildIdCard);
String buildArea = buildArea(info);
String buildAge = buildAge(info.getBirthdayDate());
Object buildSex = buildSex(info.getSex());
if(null != buildArea && !"".equals(buildArea.trim())) {
System.out.println(String.format("欢迎[%s]来自美丽里的[%s][%s]后[%s]~~",
buildIdCard, buildArea, buildAge, buildSex));
}
}
}
public static IdCardNoInfo build(String code) {
IdCardNoInfo info = new IdCardNoInfo();
info.setProvinceCode(Integer.parseInt(code.substring(0, 2)));
info.setCityCode(Integer.parseInt(code.substring(0, 4)));
info.setCountryCode(Integer.parseInt(code.substring(0, 6)));
info.setBirthdayDate(code.substring(6, 14));
info.setSex(Integer.parseInt(code.substring(14, 15)));
info.setResidentNumber(Long.parseLong(code.substring(15, 17)));
info.setValidCode(Integer.parseInt(code.substring(17)));
return info;
}
public static String buildArea(IdCardNoInfo info) {
StringBuilder sb = new StringBuilder();
URL resource = MyComeWhereUtil.class.getClassLoader().getResource("area_code.txt");
try {
FileInputStream inputStream = new FileInputStream(resource.getFile());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String str = null;
int count = 0;
while (true) {
if ((str = bufferedReader.readLine()) == null) break;
String[] strAry = str.split(";");
String code = strAry[0];
String name = strAry[1];
if (code.equals(format(info.getCountryCode()))) {
sb.append(name);
}
if (code.equals(format(info.getCityCode()))) {
sb.append(name);
}
if (code.equals(format(info.getProvinceCode()))) {
sb.append(name);
}
}
inputStream.close();
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private static Object buildSex(Integer sex) {
return sex % 2 == 0 ? "美女" : "帅哥";
}
private static String buildAge(String birthdayDate) {
Integer preYeay = Integer.parseInt(birthdayDate.substring(2, 3));
Integer lastYeay = Integer.parseInt(birthdayDate.substring(3, 4));
if (lastYeay >= 5) {
return preYeay + "5";
} else {
return preYeay + "0";
}
}
public static String format(Integer num) {
return zeroFormat(num, 6, Boolean.FALSE);
}
public static String zeroFormat(Integer num, int len, boolean prev) {
int l = num.toString().length();
StringBuffer sb = new StringBuffer();
if (!prev)
sb.append(num);//后补
for (int i = 0; i < len - l; i++)
sb.append("0");
if (prev)
sb.append(num);//前补
return sb.toString();
}
private static String buildIdCard() {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 3; i++) {
Random r = new Random();
sb.append(r.nextInt(300001) + 100000);//随机生产6位数
}
return sb.toString();
}
}
area_code.txt 由于数据量比较大,私信博主后发给大家~
这串神秘的数字最终让小讯知道了:她是谁,她来自哪儿?。
那回到我们今天所要讲解的Java数据类型,依然需要发出同样的困惑:它是谁(类型)?它来自哪儿(地址)?
3、回头看技术
3.1 Java为什么要有基础类型
我们知道Java有四大(八种)基本类型:整数型(4个)、浮点型(2个)、字符型(1个)和布尔型(1个)。
如下表格
| 数据类型 | 关键字 | 二进制位数 | 字节数 | 最大值 | 最小值 | 默认值 |
| 整数型 | byte | 8 | 1 | 127 | -128 | 0 |
| short | 16 | 2 | 32767 | -32768 | 0 | |
| int | 32 | 4 | 2,147,483,647 | -2,147,483, 648 | 0 | |
| long | 64 | 8 | 9,223,372, 036,854,770,000 | -9,223,372, 036,854,770,000 | 0L | |
| 浮点型 | float | 32 | 4 | 3.40E+38 | 1.40E-45 | 0.0f |
| double | 64 | 8 | 1.7976931348623157E308 | 4.9E-324 | 0.0d | |
| 字符型 | char | 16 | 2 | 65535 | 0 | 'u0000' |
| 布尔型 | boolean | 1 | 1 | FALSE | ||
| 引用类型 | String (or any object) | null |
记忆完这些就结束了吗?NO。
问题来了:为什么要有这些基础类型?或者为什么不统一成一种"类型",比如都是"字符型"呢?
给自己10秒钟思考时间,然后再沿着老王的思路继续......
两仪生四象,四象生八卦。
万事万物都有其根可朔,编程语言也不例外。
我们知道Java并不是世界上第一个编程语言。编程语言历史发展可谓是从低级语言(符号语言)到高级语言的过程。也就是由初期的汇编语言(编程语言鼻祖)、到中期的Fortran、Basic、Pascal结构化语言,最后到C(高级语言鼻祖)、C++、Java、Python、PHP、C#等高级语言。
如果要追溯高级语言之本,那就需要回到汇编语言本质或者编程语言的底层本质——CPU运算器。
运算器: 负责算术运算(+、-、 *、 / 基本运算和附加运算)和逻辑运算(包括移位、逻辑测试或比较两个值等)。(重点)
控制器: 负责应对所有的信息情况,调度运算器把计算做好。(科普)
寄存器: 负责对接控制器的命令,并传达命令给运算器;同时,还帮运算器记录处理完或者将要处理的数据。(科普)
综上,底层的运算器最终决定了编程语言需要有不同的数据类型。
这里需要继续发问:我们都知道CPU最终只认识0和1(再底层一些就是电路了,这里不展开讲~),但CPU到底是如何认识0和1的呢?它怎么知道谁是数值型、谁是字符型,谁是布尔型呢?
我们知道Java程序编译和运行都依赖JVM环境。JVM可以将java源代码编译后的class字节码转化为不同平台(Linux、Windows、IOS)的机器执行指令。
Java源码
public class Test {
public static void main(String[] args) {
int a = 1,b=2;
int c = a + b;
System.out.println(c); // int
float m = 1.0f, n = 2.0f; // float
System.out.println(m+n);
String str = "hello,world"; // String
System.out.println(str);
boolean flag = false; //boolean
System.out.println(flag);
}
}
汇编代码
大家可以看到,通过jvm转化后生产了对应的的汇编语言指令:
iadd: 指向了int类型的加法运算器;
fadd:指向了float的加法运算器;
ldc: 指向了字符串寄存器;
iconst_0: 将boolean指向了常量池。
大家现在明白了,为什么需要指定不同数据类型的原因了吧?
不同数据类型,底层CPU处理器不同。
3.2 Java基础类型存储在哪儿
我们知道,这些数据会存储到内存中,但是它是如何计算和存储的呢?
其本意是要考察你对Jvm运行机制的理解,是不是难度逐级上升了,如果能把该部分回答出来,进入大厂的几率和薪资都会大幅提升~~ 这部分留给你自己思考了,此处暂不深究。
提供经典Jvm运行机制图供大家参考。
在后面的章节,老王会进一步展开对Jvm运行机制的深入分析。
敬请期待,持续关注!



