《Java从小白到大牛精简版》之第5章 数据类型

2024-04-17 14:32

本文主要是介绍《Java从小白到大牛精简版》之第5章 数据类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Java从小白到大牛》纸质版已经上架了!!!
Java从小白到大牛书皮

在声明变量或常量时会用到数据类型,在前面已经用到一些数据类型,例如int、double和String等。Java语言的数据类型分为:基本类型和引用类型。

5.1 基本数据类型

基本类型表示简单的数据,基本类型分为4大类,共8种数据类型。

  • 整数类型:byte、short、int和long
  • 浮点类型:float和double
  • 字符类型:char
  • 布尔类型:boolean

基本数据类型如图5-1所示,其中整数类型、浮点类型和字符类型都属于数值类型,它们之间可以互相转换。

图5-1 基本数据类型

5.2 整型类型

从图5-1可见Java中整数类型包括:byte、short、int和long ,它们之间的区别仅仅是宽度和范围的不同。Java中整数都是有符号,与C不同没有无符号的整数类型。

Java的数据类型是跨平台的(与平台无关),无论你计算机是32位的还是64为的,byte类型整数都是一个字节(8位)。这些整数类型的宽度和范围如表5-1所示。

表 5-1 整数类型

整数类型宽度取值范围
byte1个字节(8位)-128~127
short2个字节(16位)-215~215-1
int4个字节(32位)-231~231-1
long8个字节(64位)-263~263-1

Java语言的整型类型默认是int类型,例如16表示为int类型常量,而不是short或byte,更不是long,long类型需要在数值后面加l(小写英文字母)或L(大写英文字母),示例代码如下:

public class HelloWorld {public static void main(String[] args) {// 声明整数变量// 输出一个默认整数常量System.out.println("默认整数常量  =  " + 16);     ①byte a = 16;                                ②short b = 16;                               ③int c = 16;                                     ④long d = 16L;                               ⑤long e = 16l;                               ⑥System.out.println("byte整数      =  " + a);System.out.println("short整数     =  " + b);System.out.println("int整数       =  " + c);System.out.println("long整数      =  " + d);System.out.println("long整数      =  " + e);}
}

上述代码多次用到了16整数,但它们是有所区别的。其中代码①行的16是默认整数类型,即int类型常量。代码②行16是byte整数类型。代码③行的16是short类型。代码第④行的16是int类型。代码第⑤行的16后加了L,这是说明long类型整数。代码第⑥行的16后加了l(小写英文字母l),这是也long类型整数。

提示 在程序代码中,尽量不用小写英文字母l,因为它容易与数字1混淆,特别是在Java中表示long类型整数时候很少使用小写英文字母l,而是使用大写的英文字母L。例如:16L要比16l可读性更好。

5.3 浮点类型

浮点类型主要用来储存小数数值,也可以用来储存范围较大的整数。它分为浮点数(float)和双精度浮点数(double)两种,双精度浮点数所使用的内存空间比浮点数多,可表示的数值范围与精确度也比较大。浮点类型说明如表5-2所示。

表 5-2 浮点类型

浮点类型宽度
float4个字节(32位)
double8个字节(64位)

Java语言的浮点类型默认是double类型,例如0.0表示double类型常量,而不是float类型。如果想要表示float类型,则需要在数值后面加f或F,示例代码如下:

public class HelloWorld {public static void main(String[] args) {// 声明浮点数// 输出一个默认浮点常量System.out.println("默认浮点常量  =  " + 360.66);         ①float myMoney = 360.66f;                        ②double yourMoney = 360.66;                      ③final double PI = 3.14159d;                     ④System.out.println("float整数     =  " + myMoney);System.out.println("double整数    =  " + yourMoney);System.out.println("PI      =  " + PI);}
}

上述代码①行的360.66是默认浮点类型double。代码②行360.66f是float浮点类型,float浮点类型常量表示时,数值后面需要加f或F。代码第③行的360.66表示是double浮点类型。事实上double浮点数值后面也可以加字母d或D,以表示是double浮点数,代码第④行是声明一个double类型常量,数值后面加了d字母。

5.4 数字表示方式

整数类型和浮点类型都表示数字类型,那么在给这些类型的变量或常量赋值时,应该如何表示这些数字的值呢?下面介绍一下数字和指数等的表示方式。

5.4.1 进制数字表示

如果为一个整数变量赋值,使用二进制数、八进制数和十六进制数表示,它们的表示方式分别如下:

  • 二进制数:以 0b 或0B为前缀,注意0是阿拉伯数字,不要误认为是英文字母o。
  • 八进制数:以0为前缀,注意0是阿拉伯数字。
  • 十六进制数:以 0x 或0X为前缀,注意0是阿拉伯数字。

例如下面几条语句都是表示int整数28。


int decimalInt = 28;int binaryInt1 = 0b11100;int binaryInt2 = 0B11100;int octalInt = 034;int hexadecimalInt1 = 0x1C;int hexadecimalInt2 = 0X1C;

5.4.2 指数表示

进行数学计算时往往会用到指数表示的数值。如果采用十进制表示指数,需要使用大写或小写的e表示幂,e2表示102

采用十进制指数表示的浮点数示例如下:


double myMoney = 3.36e2;double interestRate = 1.56e-2;

其中3.36e2表示的是3.36×102,1.56e-2表示的是1.56×10-2

5.5 字符类型

字符类型表示单个字符,Java中char声明字符类型,Java中的字符常量必须用单引号括起来的单个字符,如下所示:

char c = 'A';

Java字符采用双字节Unicode编码,占两个字节(16位),因而可用十六进制(无符号的)编码形式表示,它们的表现形式是\un,其中n为16位十六进制数,所以’A’字符也可以用Unicode编码’\u0041’表示,如果对字符编码感兴趣可以到维基百科(https://zh.wikipedia.org/wiki/Unicode字符列表)查询。

示例代码如下:

public class HelloWorld {public static void main(String[] args) {char c1 = 'A';      char c2 = '\u0041'; char c3 = '花';      System.out.println(c1);System.out.println(c2);System.out.println(c3);}
}

上述代码变量c1和c2都是保存的’A’,所以输出结果如下:

A
A
花

提示 字符类型也属于是数值类型,可以与int等数值类型进行数学计算或进行转换。这是因为字符类型在计算机中保存的是Unicode编码,双字节Unicode的存储范围在\u0000~\uFFFF,所以char类型取值范围0~216-1。

在Java中,为了表示一些特殊字符,前面要加上反斜杠(\),这称为字符转义。常见的转义符的含义参见表5-3。

表 5-3 转义符

字符表示Unicode编码说  明
\t\u0009水平制表符tab
\n\u000a换行
\r\u000d回车
\”\u0022双引号
\’\u0027单引号
\\u005c反斜线

示例如下:

//在Hello和World插入制表符
String specialCharTab1 = "Hello\tWorld.";
//在Hello和World插入制表符,制表符采用Unicode编码\u0009表示
String specialCharTab2 = "Hello\u0009World.";
//在Hello和World插入换行符
String specialCharNewLine = "Hello\nWorld.";
//在Hello和World插入回车符
String specialCharReturn = "Hello\rWorld.";
//在Hello和World插入双引号
String specialCharQuotationMark = "Hello\"World\".";
//在Hello和World插入单引号
String specialCharApostrophe = "Hello\'World\'.";
//在Hello和World插入反斜杠
String specialCharReverseSolidus = "Hello\\World.";System.out.println("水平制表符tab1: " + specialCharTab1);
System.out.println("水平制表符tab2: " + specialCharTab2);
System.out.println("换行: " + specialCharNewLine);
System.out.println("回车: " + specialCharReturn);
System.out.println("双引号: " + specialCharQuotationMark);
System.out.println("单引号: " + specialCharApostrophe);
System.out.println("反斜杠: " + specialCharReverseSolidus);    

输出结果如下:

水平制表符tab1: Hello    World.
水平制表符tab2: Hello    World.
换行: Hello
World.
回车: Hello
World.
双引号: Hello"World".
单引号: Hello'World'.
反斜杠: Hello\World.

5.6 布尔类型

在Java语言中声明布尔类型的关键字是boolean,它只有两个值:true和false。

提示 在C语言中布尔类型是数值类型,它有两个取值:1和0。而在Java中的布尔类型取值不能用1和0替代,也不属于数值类型,不能与int等数值类型之间进行数学计算或类型转化。

示例代码如下:

boolean isMan = true;
boolean isWoman = false;

如果试图给它们赋值true和false之外的常量,如下所示。

boolean isMan = 1;
boolean isWoman = 'A';

则发生类型不匹配编译错误。

5.7 数值类型相互转换

学习了前面的数据类型后,大家会思考一个问题,数据类型之间是否可以转换呢?数据类型的转换情况比较复杂。基本数据类型中数值类型之间可以互相转换,布尔类型不能与它们之间进行转换。但有些不兼容类型之间,如String(字符串)转换为int整数等,可以借助于一些类的方法实现。本节只讨论数值类型的互相转换。

从图5-1可见数值类型包括了byte、short、char、int、long、float和double,这些数值类型之间的转换有两个方向:自动类型转换和强制类型转换。

5.7.1 自动类型转换

自动类型转换就是需要类型之间转换是自动的,不需要采取其他手段,总的原则是小范围数据类型可以自动转换为大范围数据类型,列类型转换顺序如图5-2所示,从左到右是自动。

图5-2 数据类型转换顺序

注意 如图5-2所示,char类型比较特殊,char自动转换为int、long、float和double,但byte和short不能自动转换为char,而且char也不能自动转换为byte或short。

自动类型转换不仅发生在赋值过程中,在进行数学计算时也会发生自动类型转换,在运算中往往是先将数据类型转换为同一类型,然后在进行计算。计算规则如表5-4所示。

表5-4 计算过程中自动类型转换规则

操作数1类型操作数2类型转换后的类型
byte、short、charintint
byte、short、char、intlonglong
byte、short、char、int、longfloatfloat
byte、short、char、int、long、floatdoubledouble

示例如下:

// 声明整数变量
byte byteNum = 16;
short shortNum = 16;
int intNum = 16;
long longNum = 16L;// byte类型转换为int类型
intNum = byteNum;
// 声明char变量
char charNum = '花';
// char类型转换为int类型
intNum = charNum;// 声明浮点变量
// long类型转换为float类型
float floatNum = longNum;
// float类型转换为double类型
double doubleNum = floatNum;//表达式计算后类型是double
double result = floatNum * intNum + doubleNum / shortNum;   ①

上述代码第①行中表达式loatNum * intNum + doubleNum / shortNum进行数学计算,该表达式是由4个完全不同的数据类型组成,范围最大的是double,所以在计算过程中它们先转换成double,所以最后的结果是double。

5.7.2 强制类型转换

在数值类型转换过程中,除了需要自动类型转换外,有时还需要强制类型转换,强制类型转换是在变量或常量之前加上“(目标类型)”实现,示例代码如下:

//int型变量
int i = 10;
//把int变量i强制转换为byte
byte b = (byte) i;

上述代码(byte) i表达式实现强制类型转换。强制类型转换主要用于大宽度类型转换为小宽度类型情况,如把int转换为byte。示例代码如下:

//int型变量
int i = 10;
//把int变量i强制转换为byte
byte b = (byte) i;
int i2 = (int)i; ①
int i3 = (int)b; ②

上述代码第①行是将int类型的i变量“强制类型转换”为int类型,这显然是没有必要,但是语法也是允许的。代码第②行是将byte类型的b变量强制转换为int类型,从图5-2可见这个转换是自动,不需要强制转换,本例中这个转换没有实际意义,但有时为了提高精度需要种转换。示例代码如下:

//int型变量
int i = 10;
float c1 = i / 3; ①
System.out.println(c1); ②
//把int变量i强制转换为float
float c2 = (float)i / 3; ③
System.out.println(c2); ④

输出结果:

3.03.3333333

上述代码比较输出结果发现c1和c2变量小数部分差别比较大的,这种差别在一些金融系统中是不允许的。在代码第①行i除以3从结果是小数,但由于两个操作数都是整数int类型,小数部分被截掉了,结果是3,然后再赋值给float 类型的c1变量,最后c1保持的是3.0。为了防止两个整数进行除法等运算导致小数位被截掉问题,可以将其中一个操作数强制类型转换为float,见代码第③行,这样计算过程中操作数是float类型,结果也是float不会截掉小数部分。

再看一个强制类型转换与精度丢失的示例。

long yourNumber = 6666666666L;
System.out.println(yourNumber);
int myNuber = (int)yourNumber;
System.out.println(myNuber);

输出结果:

6666666666
-1923267926

上述代码输出结果可见,经过强制类型转换后,原本的6666666666L变成了负数。当大宽度数值转换为小宽度数值时,大宽度数值的高位被截掉,这样就会导致数据精度丢失。除非大宽度数值的高位没有数据,就是这个数比较小的情况,例如将6666666666L换为6L就不会丢失精度。

5.8 引用数据类型

在Java中除了8种基本数据类型外,其他数据类型全部都是引用(reference)数据类型,引用数据类型用了表示复杂数据类型,如图5-3所示,包含:类、接口和数组声明的数据类型。

图5-3 引用数据类型

提示 Java中的引用类型,相当于C等语言中指针(pointer)类型,引用事实上就是指针,是指向一个对象的内存地址。引用类型变量中保持的是指向对象的内存地址。很多资料上提到Java不支持指针,事实上是不支持指针计算,而指针类型还是保留了下来,只是在Java中称为引用类型。
引用数据类型示例如下:

int x = 7;      ①
int y = x;      ②String str1 = "Hello";  ③
String str2 = str1; ④
str2 = "World"; ⑤

上述代码声明了两个基本数据类型(int)和两个引用数据类型(String)。当程序执行完第②行代码后,x值为7,x赋值给y,这时y的值也是7,它们的保持方式如图5-4所示,x和y两个变量值都是7,但是它们之间是独立的,任何一个变化都不会影响另一个。

当程序执行完第③行时,字符串“Hello”对象被创建,保持到内存地址0x12345678中,str1是引用类型变量,它保存的是内存地址0x12345678,这个地址指向“Hello”对象。

当程序执行完第④行时,str1变量内容(0x12345678)被赋值给str2是引用类型变量,这样一来str1和str2保存了相同的内存地址,都指向“Hello”对象。见图5-4所示,此时str1和str2本质上是引用一个对象,通过任何一个引用都可以修改对象本身。

当程序执行完第⑤行时,字符串“World”对象被创建,保持到内存地址0x23455678中,地址保存到str2变量中,此时,str1和str2不再指向相同内存地址,见图5-5所示。

图5-4 引用数据类型赋值过程1

图5-5 引用数据类型赋值过程2

本章小结

本章主要介绍了Java中的数据类型,读者需要重点掌握基本数据类型,理解基本数据类型与引用数据类型的区别,熟悉数值类型如何互相转换。

配套视频

http://www.zhijieketang.com/classroom/6/courses

《Java从小白大牛》纸质版:

京东地址

《Java从小白大牛》电子版:

百度阅读地址

这篇关于《Java从小白到大牛精简版》之第5章 数据类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912061

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定