JAVA SE JAVA基础强袭之路 数据类型及其转换和提升全面讲解(猛男细节+保底一个收藏)

Posted Cbiltps.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SE JAVA基础强袭之路 数据类型及其转换和提升全面讲解(猛男细节+保底一个收藏)相关的知识,希望对你有一定的参考价值。

温馨提示

大家好我是Cbiltps,在我的博客中如果有难以理解的句意难以用文字表达的重点,我会有配图。所以我的博客配图非常重要!!!

而且很多知识在代码的注释里,所以代码注释也非常重要!!!

开篇介绍( 说的多一点 耐心看完哦!)

从今天开始我就写JAVA相关博客了,关于JAVA我也会做分栏【JAVA SE】和后期的【JAVA EE初阶/进阶】还有其他的课程,这篇文章是【JAVA SE】的第一篇博客!

这是一新的起点也是一个新的开始,在学习JAVA之前建议学习一下C语言的,这样JAVA前几章的知识点学习起来更容易

那博主就是先学习C语言的,所以在前面的数据类型、运算符、逻辑控制、方法会写的精简一些,相比于大多数的文章,我觉得我写的更胜一筹,所以你们不必担心文章的内容

那么,今天这篇博客的知识点在拼多多阿里巴巴快手猿辅导等公司常考!!!

本章重点

  • 常量及变量
  • 数据类型的详细介绍
  • 类型转换及数值提升

正文开始


1. 变量和类型


1.1 常量

什么是常量?
常量就是程序在运行的时候不能修改的量

常量的分类:

  • 字面值常量
  • final修饰的变量(也叫常量)
//字面值常量
10    // int 字面值常量(十进制)
010   // int 字面值常量(八进制) 由数字 0 开头, 010 也就是十进制的 8
0x10  // int 字面值常量(十六进制) 由数字 0x 开头, 0x10 也就是十进制的 16
10L   // long 字面值常量. 也可以写作 10l (小写的L)
1.0   // double 字面值常量. 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科学计数法表示, 相当于 1.5 * 10^2
1.0f  // float 字面值常量, 也可以写作 1.0F
true  // boolen 字面值常量, 同样的还有 false
'a'   // char 字面值常量, 单引号中只能有一个字符
"abc" // String 字面值常量, 双引号中可以有多个字符
final int a = 10;//final关键字修饰的常量
a = 20;//如果想要修改它的值,就会报错(运行图如下)

注意:常量在编译的时候就已经确定其值是什么了(只能初始化一次)!

1.2 变量

变量指的是程序运行时可变的量创建变量相当于开辟一块内存空间(冯·诺依曼体系中,这个所谓的内存空间就是内存储器保存一些数据

1.2.1 变量的作用域

本章针对的是局部变量的作用域,说明还有其他种类的变量,在类和对象的博客中会有详细讲解,到时候贴链接,大家敬请期待!!!

关于作用域完全和C语言的是一样的,也就是该变量能生效的范围, 一般是变量定义所在的代码块 (花括号)之内

1.2.2 变量的命名规则(阿里巴巴开发手册)

1.3 基本数据类型

类型是对变量的种类进行了划分,不同类型的变量具有不同的特性(下图是JAVA中的类型汇总)。


注意:这里的默认值不是局部变量的默认值!!!

1.3.1 整型变量(重点)

基本语法格式:

int 变量名 = 初始值;
int a = 1;

取值范围(写下面的代码可以直接看):

public class Main {

    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE);//int的最大值 打印出来是 2147483647
        System.out.println(Integer.MIN_VALUE);//int的最小值 打印出来是 -2147483648
    }//4个字节(int类型)表示的数据范围是 -2^31 -> 2^31-1 , 也就大概是 -21亿 到 +21亿。
}

// 这里的Integer大家可以认为是int的plus版本,术语叫做包装类,后期会讲到!

变量在定义的时候不初始化,可不可以?(看下图就知道)
不可以,JAVA比较安全,如果不初始化就使用,编译器会报错。注意不是警告!!!

一个运算题:

int a = 1;
int b = 2;
System.out.println(a / b);//结果是 0
//Java中,int除以int的值仍然是int(会直接舍弃小数部分),如果想得到0.5, 需要使用double类型计算

//而且,JAVA中不存在截断的情况,如
int a = 1.1;
//等号左边是int类型,右边是double类型,这样是错的!

注意:

  • JAVA中的int类型大小不管操作系统是多少位的,都是4个字节
    这一点说明JAVA的可移植性强(一次编译,到处运行)!
  • JAVA中的int类型没有无符号类型,统一都是有符号的,所以第一位是符号位!

1.3.2 长整型变量

基本语法格式:

long 变量名 = 初始值;
long num = 10L; //定义一个长整型变量, 初始值写作 10L 也可以 10l ,不是数字1
//建议使用大写 L 做后缀

取值范围(写下面的代码可以直接看):

public class Main {

    public static void main(String[] args) {
        System.out.println(Long.MAX_VALUE);
        System.out.println(Long.MIN_VALUE);
    }//Java中 long类型 占8个字节. 表示的数据范围 -2^63 -> 2^63-1
}

注意:JAVA中没有long long类型!

1.3.3 双精度浮点型变量(重点)

基本语法格式:

double 变量名 = 初始值;
double num = 1.0;

一个问题:

double num = 1.1;
System.out.println(num * num);//看下图


我们看到执行结果为1.2100000000000002,这是为什么?
其实在程序里,小数里是没有精确的数字的,只能精确到前几位(float只能精确到前6位)。

注意:关于数据的存储,大家看我的这篇博客!

  • Java中的double类型虽然也是8个字节,但是浮点数的内存布局和整数差别很大, 不能单纯的用 2^n 的形式表示数据范围!

  • Java的double类型的内存布局遵守 IEEE 754标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差!

1.3.4 单精度浮点型变量

基本格式:

float 变量名 = 初始值;
float num = 1.0f; // 写成 1.0F 也可以

特别注意(错误演示):

float a = 1.2;//这样初始化是错的,系统会报错!
//1.2默认是double类型,从double转换到float可能会有损失!

//但是在C语言中最多一个警告!

//由此看出:JAVA是强类型语言,C语言是弱类型语言

所以:初始化的时候一定要加 l或者L

  • float类型在Java中占四个字节, 同样遵守IEEE 754标准,由于表示的数据精度范围较小,,一般在工程上用到浮点数都优先考虑double不太推荐使用float

1.3.5 字符类型变量

基本格式:

char 变量名 = 初始值;
char ch = 'A';

cahr ch2 = 97;//char类型初始化为97,打印出来是a!
//虽然初始化是整数,但是会解析成字符,计算机上的字符本质是一个整数!
//在C语言中使用ASCII表示字符, 而Java中使用Unicode表示字符(大家可以百度一下Unicode)!

字符类型的大小(上代码):

char a = '你';
System.out.println(a);


上图可以运行,但是注意汉字是两个字节的!
所以:JAVA中char类型两个字节(C语言是一个字节)!

但是,JAVA中使用汉字在执行javac的时候可能出现以下错误:

此时我们在执行javac时加上-encoding UTF-8即可编译

如果上面的操作没整明白的话,我会单独出一篇博客!

到时候贴链接,大家敬请期待!

1.3.6 字节类型变量

基本语法格式:

byte 变量名 = 初始值;
byte a = 10;

注意字节类型表示的也是整数,只占一个字节, 表示范围较小 ( -128 -> +127 )

1.3.7 短整型变量

基本语法格式:

short 变量名 = 初始值;
short a = 10;

注意short类型占用2个字节, 表示的数据范围是-2^15 -> 2^15-1( -32768 -> +32767),范围比较小, 一般不推荐使用。

1.3.8 布尔类型变量

基本语法格式:

boolean 变量名 = 初始值;
boolean a = true;
boolean b = false;

那我们和C语言中的布尔类型做一下比较:

//C语言中  0表示假 非0表示真

//那在java中这样初始化布尔类型可以吗?
boolean a = 0;//这样是错的!
//Java中boolean只有两个取值,要么是true,要么是false,不能有其他取值!

boolean value = true;
System.out.println(value + 1);//所以,这样的代码更不能写了

布尔类型的大小:

在JVM的规范中,并没有规定布尔类型的大小,有些书上说是一个bit(比特)位,有些书上说是一个(byte)字节!

但是注意:当我们在刷题的时候,预见这样的问题(如下)

假设有四个选项,让你找出哪一个是对的?

技巧就是你看其他三项是不是明显错误的,一旦有更适合的答案,就选它

1.3.9 字符串类型变量(重点)

String类型(字符串类型)也叫引用类型,引用类型有很多(String、数组、接口、类、枚举等),如何去判断就要看它存储的是不是地址(关于引用类型后期会写到)。

基本语法格式:

String 变量名 = "初始值";
String name = "daxiangzi";//把一些字符放到一起就构成了字符串

字符串相加:

System.out.println("daxiangzi");
System.out.println("da"+"xiangzi");
//这样打印出来会是什么?


结果拼到一起了,所以这里的+加号有拼接的作用!

字符串加数字:

System.out.println("hello"+10+20);//结果会是hello30吗?


结果居然是hello1020,这是为什么?

原因就是其他数据类型字符串类型使用+加号拼接结果就是一个字符串

但是有特例:

System.out.println(10+20+"hello");//这样子写就是30hello


原因就是计算机在运算的时候从左往右算,然后拼接字符串hello)最后变成了新的字符串(30hello) !

如果想要结果是hello30

System.out.println("hello"+(10+20));//这样写即可,就是添加括号


想要结果是1020hello

System.out.println(10+""+20+"hello");//中间加一个空字符串即可


问一个问题:如果想输出结果是"bit"要怎么办?

这个时候就要用到转义字符

System.out.println("\\"bit\\"");


转义字符有很多,其中常见的如下:

注意:''单引号引起的是字符,""双引号引起的是字符串(若干字符)!

2. 类型转换及数值提升

2.1 类型转换

Java作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验(先看以下几个代码场景)。

2.1.1 int 和 long/double 相互赋值

那我们直接上代码:

int a = 10;
long b = a;//这样写是可以的,int(四个字节)可以放到long(八字节)里
System.out.println(b);

但是反过来就不行了

long p = 12;
int q = p;//这样会报错,类型不兼容,不能说是12不能放进int里

但是如果一定要放进去,就要强制类型转换,这样有可能损失精度(有风险)

int q = (int)p;

这里转换double类型就是不举例了,道理相同!

2.1.2 int 和 boolean 相互赋值

int a = 10;
boolean b = a;//类型不匹配直接报错
boolean c = (boolean)a;//就算强制类型转换也不行 

同样的boolean转换int也是不行的!

2.1.3 int 和 String 之间的相互转换

这个转换比较特殊,直接上代码(int转换String):

int num = 10;
String ret = String.valueOf(num);//Java中可以直接调用方法把int转换成String
System.out.println(ret);

还有一种方法:

System.out.println(num+"");//这样也行,但是不可取

String转int

这里就要引入包装类的好处了
就是里面有很多写好的方法(函数),可以随意调用

String a = "123";
int ret = Integer.valueOf(a);//调用方法把int转换成String
System.out.println(ret);

2.2 数值提升

所有的类型提升为了什么
其实就是为了提升效率

2.2.1 int 和 long 混合运算

int a = 10;
long b = 20;
int c = a + b;//这样会报错,为什么呢?
int c = (int)(a + b);//除非这样强制类型转换

long d = a + b;//编译通过

intlong混合运算的时候, int会提升成long, 得到的结果仍然是long类型, 需要使用long类型的变量来接收结果,如果非要用int来接收结果(类型不匹配报错), 就需要使用强制类型转换

2.2.2 byte 和 byte 的运算

byte a = 1;
byte b = 2;
byte c = a + b;//表面上看着没问题,但是会报错

这里的byte小于四个字节的,对于CPU来说,运算的时候会发生整型提升

所以,a和b 就是int类型,c是byte类型不匹配就会报错!

为了解决问题,就使用强制类型转换,但有可能会损失精度

byte c = (byte)(a + b);
System.out.println(c);

但是下面的代码(不会报错):

byte c2 = 1 + 2;//不会报错

这是因为此时的1和2是整形的字面值常量,编译的时候直接把1+2当作3了,使用字面值常量赋值的时候, Java会自动进行一些检查校验, 判定赋值是否合理

最后特此强调:关于整形提升(隐式类型转换),博主之前在【C语言初阶】关于操作符的文章(在后面部分的表达式求值小节)里有详细的讲解,大家一定要去看!!!

全文结束

本来想写的精简一些的,但是发现我他喵本根精简不起来!!!

一个数据类型就快一万字了,不敢想象后期的类与对象的文章有多少!!!

希望大家多多支持点赞!!!

您的鼓励就是我最大的动力!!!

以上是关于JAVA SE JAVA基础强袭之路 数据类型及其转换和提升全面讲解(猛男细节+保底一个收藏)的主要内容,如果未能解决你的问题,请参考以下文章

Java面试之SE基础基本数据类型

java基础之路

Java面试总结之SE基础基本数据类型

Java SE第二章:基础数据类型

JAVA基础学习之路数组的定义

深入Java基础——基本数据类型及其包装类