Java数据类型
回顾
Java历史
Java第一个程序
搭建开发环境
- 下载
- 安装
- 配置:Path环境变量
JDK
JRE
JVM
CMD常用命令
-
盘符切换 e:
-
路径切换 cd xx
-
查找文件 dir xxx
javac.exe 编译java源文件
java.exe 执行Java程序(加载类到虚拟机中)
注释
-
作用
为了方便程序的阅读,Java语言允许程序员在程序中写上一些说明性的文字,用来提高程序的可读性,这些文字性的说明就称为注释。 注释不会出现在字节码文件中,即Java编译器编译时会跳过注释语句。
-
分类
- 单行注释 // 注释内容从//开始到本行结束。
- 多行注释 /* */ 在需要长篇注释时,可用多行也可用多个单行注释,多行注释不能嵌套。
- 文档注释 /** */ 可用生成doc文档
-
生成doc文档
-
首先编写java类,写好文档注释
-
通过命令行用javac编译该类文件
-
通过命令javadoc命令生成帮助文档,文档供使用者或其他开发人员阅读,查询使用
-
生成 Javadoc 不要求你的Java代码是可编译的,唯一要求的是存在.java文件。
Javadoc是java内置工具,用于生成API文档
-
ex-Javadoc -d myhelp -version -author User.java
-
其中-d表示生成文档的路径,表示在当前路径的myhelp文件夹下生成,-version表示生成version信息,-author表示生成author信息
-
https://blog.csdn.net/fanxiaobin577328725/article/details/52658781
-
变量(在一定范围内可以改变的量)
-
程序:数据+算法
-
可以改变的量
未知数x
变量能够表示的数据领域不局限于数字。name = “张三”; name = “李四”;name就是一个变量
-
本质是内存空间的一块存储区域,通过变量名就可以访问它
系统会为它开辟一块内存空间来保存数据,本质上就是代表一个”可操作的存储空间”,空间位置是确定的,但是里面放置什么值不确定。我们可通过变量名来访问“对应的存储空间”,从而操纵这个“存储空间”存储的值。 变量作为程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。变量在使用前必须对其声明, 只有在变量声明以后,才能为其分配相应长度的存储空间。
-
定义:
- 内存中的一个存储区域
- 该区域有自己的名称(变量名)和类型(数据类型)
- 该区域的数据可以在同一类型范围内不断变化。
-
声明方式:
- 先声明,后赋值
- 声明的同时初始化
-
语法:
- [访问标识符]+变量数据类型+变量名[=变量值];
- 变量也可以批量的进行声明,如int a,b,c;此时,java会批量的分配空间给这些变量。但不建议这样声明。
-
注意事项
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符
- 变量声明是一条完整的语句,因此每一个声明都必须以分号结束
- 定义变量又叫声明变量。定义变量有什么作用?我们知道编程是一个代码量十分庞大的过程,我们提倡使用最简洁的代码实现功能。而变量它可以用来存放同一类型的常量,并且在作用域范围内是可以重复使用,这在一定程度上为优化代码的提供了很大的方便。
- 使用变量需要的注意:一是变量的作用范围(一定是在定义变量的一对{}之间有效)。二是变量的初始值,在定义变量时,可以不赋予初始值。如果需要使用到变量一定先初始化,即赋予初始值。
- 变量的作用域:其定义所在的一对{ }内,同一个作用域内,不能定义重名的变量
- 变量只有在其作用域内才有效
常量
常量代表程序运行过程中不能改变的值。
常量的语法格式和变量类型:只需要在变量的语法格式前面添加关键字final即可。在Java编码规范中,要求常量名必须大写。
则常量的语法格式如下:
final 数据类型 常量名称 = 值;
final 数据类型 常量名称1 = 值1, 常量名称2 = 值2,……常量名称n = 值n;
例如:final double PI = 3.14; final char MALE=‘M’,FEMALE=‘F’;
在Java语法中,常量也可以首先声明,然后再进行赋值,但是只能赋值一次,示例代码如下:
final int UP;
UP = 1;
Java中常量的分类:
1,整数常量。所有整数
2,小数常量。所有小数
3,布尔(boolean)型常量。较为特有,只有两个数值。true false。
4,字符常量。将一个数字字母或者符号用单引号( ’ ’ )标识。
5,字符串常量。将一个或者多个字符用双引号(“ ”)标识。
6,null常量。只有一个数值就是:null.
垃圾回收机制
- 不再使用的内存空间应回收—— 垃圾回收
- 在C/C++等语言中,由程序员负责回收无用内存。
- Java 语言消除了程序员回收无用内存空间的责任:它提供一种系统级线程跟踪存储空 间的分配情况。并在JVM空闲时,检查并释放那些可被释放的存储空间。
- ·垃圾回收在Java程序运行过程中自动进行,程序员无法精确控制和干预。
Java程序还会出现内存泄漏和内存溢出问题吗?------答:会
- 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
- 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要
- 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次
- 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏
数据类型
-
分类:
- 基本数据类型(8种),也叫源生数据类型
- 引用数据类型(4字节,存储地址)
-
八种基本数据类型
数据类型 关键字 在内存中占用字节数 数值范围 默认值 布尔型 boolean 1字节(8位) true,false false 字节型 byte 1字节(8位) -128~127 0 字符型 char 2字节(16位) 0~65535 ‘\u0000’ 短整型 short 2字节(16位) -32768~32767 0 整形 int 4字节(32位) -231~231-1 0 长整形 long 8字节(64位) 正负9开头的19位数 0L 单精度浮点型 float 4字节(32位) 正负39位数 0.0F 双精度浮点型 double 8字节(64位) 正负309位数 0.0D -
char 类型用来表示在Unicode编码表中的字符。Unicode编码被设计用来处理各种语言的文字,它占2个字节,可允许有65536个字符。Unicode具有从0到65535之间的编码,他们通常用从’\u0000’到’\uFFFF’之间的十六进制值来表示(前缀为u表示Unicode),‘0’~‘9’: 4857;‘a’~‘z’: 97~122;’A‘ ~ ’Z‘: 65~90;
-
boolean类型的大小争议问题:
boolean类型只有true和false两个值,存储需要一个bit即可,所以认为boolean的大小是1个bit,但是boolean的数组存储时JVM是作为byte类型存储,即每个boolean元素的大小为1字节即8bit,所以认为boolean的大小是1字节,而单个的boolean变量,JVM是用int类处理,即编译器给JVM时是将boolean作为int类型,所以JVM处理也用int类型,所以认为其大小是4字节。但都是Oracle的JVM规范,其他的JVM可能不一样,由于boolean的类型java规范并没有明确规定其大小,所以一般是由JVM控制,而且JVM没有专门用于操作boolean的指令,所以是将其值用1和0来操作,但是boolean的值不能用1和0代替,只是JVM用1和0来操作,1代表true,而数字Oracle的JVM是用int来存储,所以有了以上观点。
-
long类型声明时一般数值后面要加上l或者是L,因为默认写的数字是int类型的。比如byte x=30;实际30也是作为int类型的,但是由于30没有超出byte的范围,自动转换没有问题,而用long声明一个超出int范围的数值时会直接报错,如果是不超出int的,依然没有问题。
long a = 55555555; //编译成功,在int表示的范围内(21亿内)。 long b = 55555555555;//不加L编译错误,已经超过int表示的范围 long b = 55555555555L;//正确
-
float类型又被称作单精度类型,尾数可以精确到7位有效数字,在很多情况下,float类型的精度很难满足需求。而double表示这种类型的数值精度约是float类型的两倍,又被称作双精度类型,绝大部分应用程序都采用double类型。浮点型常量默认类型也是double。
-
Java浮点类型常量有两种表示形式
十进制数形式,例如:3.14 314.0 0.314
科学记数法形式,如314e2 314E2 314E-2
double f = 314e2; //314*10^2-->31400.0 double f2 = 314e-2; //314*10^(-2)-->3.14
-
浮点型变量赋值时都是默认为double类型的,所以如果是float a=3.14会出错,必须是float a=3.14F;
float f = 3.14F; double d1 = 3.14; double d2 = 3.14D;
-
浮点类型float,double的数据不适合在不容许舍入误差的金融计算领域。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类
float f = 0.1f; double d = 1.0/10; System.out.println(f==d);//结果为false
float d1 = 23456789f; float d2 = d1+1; if(d1==d2){ System.out.println("d1==d2");//输出结果为d1==d2 }else{ System.out.println("d1!=d2"); }
运行以上两个示例,发现示例1的结果是“false”,而示例2的输出结果是“d1==d2”。这是因为由于字长有限,浮点数能够精确表示的数是有限的,因而也是离散的。 浮点数一般都存在舍入误差,很多数字无法精确表示(例如0.1),其结果只能是接近, 但不等于。二进制浮点数不能精确的表示0.1、0.01、0.001这样10的负次幂。并不是所有的小数都能可以精确的用二进制浮点数表示。
java.math包下面的两个有用的类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点运算。
import java.math.BigDecimal; public class Main { public static void main(String[] args) { BigDecimal bd = BigDecimal.valueOf(1.0); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); System.out.println(bd);//0.5 System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);//0.5000000000000001 } }
-
-
引用数据类型
String是一种声明字符串的数据类型,它是引用数据类型(它是一个对象)
string:字符串,“ ”,“Hello World”,“你好,java”
-
java中常用的转义字符
- \n表示换行
- \t表示制表符,相当于Tab键
- \r表示回车,相当于Enter键
- \b表示退格,相当于Backspace键
- 特殊字符需要转义,如|,/等
基本数据类型转换
-
背景
8种基本数据类型当中,我们会发现有7种都可以表示数字。
所以,7种数值类型之间可以互相转换 -
自动类型转换(隐式转换):数据类型兼容,小转大
int a = 3; long b = a; // long <-- int 自动类型转换
-
强制类型转换又被称为造型:数据类型兼容,大转小,丢失精度或溢出
long m = 3; int n = m; // 会报错 int n = (int)m; // int <-- long 强制类型转换
-
大,小是指数据范围的大小
- 数据范围大小为(从小到大):byte→short(char)→int→long→float→double
- 字符可以和整数进行转换
-
表达式类型自提升
- 所谓表达式是指由变量和运算符组成的一个算式。变量在表达式中进行运算时,也有可能发生自动类型转换,这就是表达式数据类型的自动提升,如一个byte型的变量在运算期间类型会自动提升为int型。byte b = 3;int x = 4;x = x + b;//b会自动提升为int类型进行运算。
- byte b = 3;
b = b + 4;//报错
b = (byte)b+4;//强制类型转换,强制将b+4的结果转换为byte类型,再赋值给b。
-
自测
- float <-- long
long m = 3; float f = m; // 自动类型转换
- char <-- byte
byte b = 3; char c = (char)b; // 强制类型转换
- byte <-- char
char c = 3; byte b = (byte)c; // 强制类型转换
- float <-- long
-
总结
只和【数值范围】有关;自动类型转换指的是容量小的数据类型可以自动转换为容量大的数据类型。如图2-6所示,黑色的实线表示无数据丢失的自动类型转换,而虚线表示在转换时可能会有精度的损失
-
范围溢出问题
-
将超出数据类型范围的数字强制转换时出现
public void test1(){ long b = 20000000000L; int a = (int)b; //结果为-1474836480 System.out.println(a); }
-
运算结果超出范围,赋值时出现
public void test1(){ int a = 100; int b = 200000000; int c = a*b; //结果为-1474836480 System.out.println(c); }
当表示int的最大值再加上一以后,就溢出,其结果变为int的最小值。当加上二以后表示为次小值,相当于钟表,当超出12点以后从新从最小的1开始。超出多少就是最小值上开始加多少。
-
标识符命名规范
-
目的
在不违背语法的前提下增强可读性,用来表示某个实体的符号,即为代码中的部分内容起的名称。简单来说,在Java中自己起名字的地方使用的就叫标识符,用来给变量、类、方法以及包进行命名的,如Welcome、main、System、age、name、gender等。标识符需要遵守一定的规则:
-
首字母
A~Z a~z _ $ 合计54个字符(26个大写英文字母+26个小写英文字母+下划线+美元符号)
-
其它字符
0~9 A~Z a~z _ $ 合计64个字符(在54个字符的基础上,增加0~9这10个数字)
-
标识符不能包含空格。
-
Java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等。保留字是为java预留的关键字,他们虽然现在没有作为关键字,但在以后的升级版本中有可能作为关键字。
-
"
-
避开关键字(保留字)https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html
Java中的关键字要避开
int int = 3; // 错误的,int是关键字,不可以作为标识符 int class = 5; // 错误的,class是关键字,不可以作为标识符
-
驼峰命名法
从第二个单词开始,每个单词的首字母大写
double myEnglishAverageScore = 90; ---------------------------------- // 如果要求必须全小写 double my_chinese_average_score = 90; // 如果要求必须全大写 double MY_ENGLISH_AVERAGE_SCORE = 90;
- Java 标识符大小写敏感,且长度无限制。不要用拼音
- 表示类名的标识符:每个单词的首字母大写,如Man, GoodMan
- 表示方法和变量的标识符:第一个单词小写,从第二个单词开始首字母大写,我们称之为“驼峰原则”,如eat(), eatFood()
- Java不采用通常语言使用的ASCII字符集,而是采用Unicode这样标准的国际字符集。因此,这里字母的含义不仅仅是英文,还包括汉字等等。但是不建议大家使用汉字来定义标识符!
- 命名规则,不受语法约束,建议遵守
- 包名:多单词组成时所有字母均小写,使用.连接
aaa.bbb.ccc
- 类名&接口名:大驼峰式 AaaBbbCcc
- 变量名&方法名:小驼峰式 aaaBbbCcc
- 常量名:多单词组成是所有字母均大写,使用_连接
AAA_BBB_CCC
- 包名:多单词组成时所有字母均小写,使用.连接
常见英文单词
略
name
sex / gender 性别
age
score 分数
major 专业
salary 薪水
department 部门
Scanner初识
-
从键盘获取输入
-
导包:import java.util.Scanner;
-
接收整数
int a = Scanner对象.nextInt();
- 接收小数
double b = Scanner对象.nextDouble();
- 接收字符
char a = Scanner对象.next().charAt(0);
- 接收字符串
String name = Scanner对象.next(); // 以空格、Tab、换行符为结束符 区别2暂时不说
String name2 = Scanner对象.nextLine(); // 以换行符为结束符,可以接收一整行字符串 区别2暂时不说
Q:编码GBK的不可映射字符
- 解决方案
(NotePad++)编码 – 转为ANSI编码 – 保存
编码表
char是数字,同一个数字,在不同的编码表中,对应的字符是不同的。
就好比,o 在不同的老师眼中是不同的含义。
语文老师:句号,表示语句的结束
数学老师:数字0
英语老师:字母o
化学老师:氧元素
进制转换
https://blog.csdn.net/zhiyeegao/article/details/82227580
https://blog.csdn.net/final__static/article/details/89405945
十进制
-
满十进一
-
0~9
-
千百十个
千 百 十 个 9 8 6 9 * 100 + 8 * 10 + 6 * 1 == 986
二进制
-
前缀 0b或0B
-
满二进一
-
0~1
-
八四二一
八 四 二 一 1 0 1 1 1 * 8 + 0 * 4 + 1 * 2 + 1 * 1 == 8 + 2 + 1 == 11 十六 八 四 二 一 1 0 0 1 0 1 * 16 + 1 * 2 == 16 + 2 = 18 规范写法:0b110
八进制
-
前缀 0
-
满八进一
-
0~7
-
512 64 8 1
512 64 8 1 1 7 1 * 8 + 7 * 1 = 8 + 7 == 15 规范写法:017
十六进制
-
前缀 0x 或 0X
-
满十六进一
-
0~9,A,B,C,D,E,F
-
4096 256 16 1
4096 256 16 1 A C E A : 10 10 * 256 == 2560 C : 12 12 * 16 == 192 E : 14 14 * 1 == 14 0xACE == 2766
任意进制 --> 十进制
一位一位数,求和
十 --> 其它进制
-
整数部分:除以进制数,取余。从下往上读
-
十 --> 二
2 | 123 |------- 2 | 61 ······ 1 ↑ |----- ↑ 2 | 30 ······ 1 ↑ |---- ↑ 2 | 15 ······ 0 ↑ |---- ↑ 2 | 7 ······ 1 ↑ |--- ↑ 2 | 3 ······ 1 ↑ |--- ↑ 2 | 1 ······ 1 ↑ |--- ↑ 0 ······ 1 ↑ 结果:0b1111011
-
十 --> 八
8 | 123 |------- 8 | 15 ······ 3 ↑ |----- ↑ 8 | 1 ······ 7 ↑ |---- ↑ 0 ······ 1 ↑ 结果:0173
-
十 --> 十六
16 | 123 |------- 16 | 7 ······ 11 ↑ |----- ↑ 0 ······ 7 ↑ 结果:0x7B
-
-
小数部分:乘以进制数,取整。从上往下读
-
十 --> 二
0.375 --> 0b0.011 0.25 + 0.125 == 0.375
-
-
原理
十 --> 十
整数部分:
1982641874 --> 19亿8264万1874
从右往左数个数的时候,其实是小数点左移的过程。
小数点左移:除以进制数
除以十,余4(最低位)
除以十,余7
除以十,余8
……………………
除以十,余1 (最高位)
先得到的余数是距离小数点最近的位(最低位),所以从下往上读。
小数部分:
0.187236 --> 十
乘以十,整数是1 (最高位)
乘以十,整数是8
…………………………
乘以十,整数是6 (最低位)
先得到的是最高位,从上往下读
*Q : 为什么同样是4个字节的存储空间,int只能表示正负21亿,而float可以表示39位数呢?
int 4个字节
0 000 0000 0000 0000 0000 0000 0000 0000
符号位 : 0表示正,1表示负
数值部分:0~2的31次方
float 4个字节
0 00000000 00000000000000000000000
符号位:0为正数,1为负数
指数部分:8个bit位 -128~127
尾数部分:23个bit位
因为有指数位,所以范围会比int类型大很多很多。float的尾数位决定了float的精度。 float在内存中是按ieee754标准存储的。int32 在内存中的分配是:1bit(符号位)31bits(实际数字位) float 在内存中的分配情况是:1bit(符号位) 8bits(指数位) 23bits(尾数位) int32 的实际数字位决定了int32的范围; float的指数位决定了float的范围
float的精度是6~7位
【参考网址】https://blog.csdn.net/a327369238/article/details/52354811
32个bit位,最多最多能表示2的32次方个数
所以float作弊了,它无法准确表示出数值范围内的每一个数字,简言之,它作弊了。
double与float同理。
*Q:数值部分为0时,符号位有什么意义
【参考网址】https://blog.csdn.net/lanchunhui/article/details/50704201
总结
- 注释可以提高程序的可读性。可划分为
- 单行注释 //
- 多行注释 /…/
- 文档注释 /**…*/
- 标识符的命名规则:
- 标识符必须以字母、下划线_、美元符号$开头。 _
- 标识符其它部分可以是字母、下划线“”、美元符“$”和数字的任意组合。
- Java 标识符大小写敏感,且长度无限制。
- 标识符不可以是Java的关键字。
- 标识符的命名规范
- 表示类名的标识符:每个单词的首字母大写,如Man, GoodMan
- 表示方法和变量的标识符:第一个单词小写,从第二个单词开始首字母大写,我们称之为“驼峰原则”,如eat(), eatFood()
- 变量的声明格式:type varName [=value][,varName[=value]…];
- 变量的分类:局部变量、实例变量、静态变量
- 常量的声名格式final type varName = value ;
- Java的数据类型可分为基本数据类型和引用数据类,基本数据类型的分类如下:
- 整型变量:byte、short、int、long
- 浮点型:float、double
- 字符型:char
- 布尔型:boolean,值为true或者false
- 基本数据类型的类型转换可分为:
- 自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型
- 强制类型转换:用于显式的转换一个数值的类型,语法格式:(type)var
- 键盘的输入:Scanner类的使用
作业
一、选择题
1.以下选项中属于合法的Java标识符的是( )。(选择二项)
A.public
B.3num
C.name
D._age
2.下面的代码段中,执行之后i和j的值是( )。(选择一项)
int i=1; int j;
j=i++;
A1,1
B.1,2
C.2,1
D.2,2
3.下面的赋值语句中错误的是( )。(选择一项)
Afloat f = 11.1;
B.double d = 5.3E12;
C.double d = 3.14159;
D.double d = 3.14D;
4.在Java中,下面( )语句能正确通过编译。(选择二项)
ASystem.out.println(1+1);
B.char i =2+‘2’;
System.out.println(i);
C.String s=“on”+‘one’;
D.int b=255.0;
5.以下Java运算符中优先级别最低的两个选项是( )。(选择二项)
A赋值运算符=
B.条件运算符 ?=
C.逻辑运算符|
D.算术运算符+
二、简答题
1.Java是一种强类型语言,说明Java的数据类型分类。
2.i++和++i的异同之处
3.运算符||和|的异同之处
4.Java中基本数据类型转换的规则
三、编码题
-
定义类:Test1,定义main()方法,分别定义8种数据类型的变量,并赋初始值;然后打印每种类型的变量。
-
定义类:Test2,定义main()方法,请按如下要求编写代码:
(1)定义一个byte类型的变量v1,赋初始值;将v1赋给一个int类型的变量v2。将v2赋给一个long类型的变量v3;将v3赋给一个double类型的变量v4;(2) 打印每个变量的值。
-
要求在控制台打印以下数据(利用常量的方式):
(1)字符串常量 “不忘初心方得始终”
(2)整数常量 88,-88
(3)小数常量 88.888
(4)字符常量 ‘A’,‘8’
(5)布尔常量 true,false。
-
在键盘上输入你的姓名、性别、年龄、身高,然后打印输出
-
输入圆形半径,求圆形的周长和圆形的面积,并将结果输出。
- 银行利率表如下表所示,请计算存款10000元,活期1年、活期2年,定期1年,定期2年后的本息合计。
结果如下图所示(结果四舍五入,不保留小数位。使用Math.round(double d)实现)。
- 某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。结果如图所示。
预习任务
运算符
算数运算符
-
%
-
++
赋值运算符
关系运算符
- ==
- !=
逻辑运算符
- &&
- ||
*位运算符 (不要求手算)
- 二进制
- 原码
- 反码
- 补码