变量概述
变量:常量是固定不变的数据,那么在程序中可以变化的量称为变量。
变量:计算机要进行运算必须能够保持住参加运算的数据,首先数据要进入内存存放在内存中,为了方便找到并使用这些数据,那么必须要对它们进行标示,这种标识符所表示的数据就成为变量。因此变量用来标示内存中的一份数据。变量表示的数据可以在程序执行过程中进行改变,变量一旦改变就使用改变后的值。
变量的使用:
1.变量的声明:指明变量的名称及所属的数据类型。基本语法:数据类型 变量名;
2.变量的赋值,把一份数据指定给某个变量去表示,赋值可以改变变量的值。基本语法:变量名=值;
规范:JAVA语言是“强类型的语言”,它要求变量必须具有明确的数据类型,主要是因为在编译期需要给变量精确的分配内存,也需要确定表达式的精确的结果类型等。
数据类型:就是对程序中所使用数据的分类,数据就是用来标示信息的。作为信息的描述来看,不同种类的信息表达方式是不同的,比如人的 名称应归类为 字符串,比如菜的重量归类为小数,人的年龄应归类为正数等。
Java的数据类型分为两大类: 基本数据类型:包括 整数 、 浮点数 、 字符 、 布尔 。
引用数据类型 有四种:包括 类类型 、 接口类型 、类型变量(泛型) 、数组类型、还有一个特殊的空类型。
null类型,即表达式的类型null,没有名称。
由于空类型没有名称,因此无法声明空类型的变量或将其强制转换为空类型。
空引用是空类型表达式的唯一可能的值。
空引用总是可以被分配或浇铸任何引用类型。
在实践中,程序员可以忽略null类型,而只是假装这null只是可以是任何引用类型的特殊文字。
基本数据类型
基本数据类型 有八个 :四个是 整数,两个是小数,其他的 是字符和布尔。
四类八种基本数据类型
了解各类型数据的表示范围,有利于给不同的数据声明为不同类型的合适的变量。
补充:JAVA是面向对象的,原本没有基本数据类型,只是代码中有很多数据用基本类型来表示更加简单直接,所以得以保留。但是,所有的基本类型的数据都可以用它对应的引用类型(包装类型,java中的八个基本类型有八个对应的包装类型,它们之间可以方便地进行互相转换,这种转换操作表示为“装箱”和拆箱)来表示。
代码展示
public static void main(String[] args) {
System.out.println("byte的表示范围从"+Byte.MIN_VALUE+"至"+Byte.MAX_VALUE);
System.out.println("short的表示范围从"+Short.MIN_VALUE+"至"+Short.MAX_VALUE);
System.out.println("int的表示范围从"+Integer.MIN_VALUE+"至"+Integer.MAX_VALUE);
System.out.println("long的表示范围从"+Long.MIN_VALUE+"至"+Long.MAX_VALUE);
System.out.println("float的表示范围从"+Float.MIN_VALUE+"至"+Float.MAX_VALUE);
System.out.println("double的表示范围从"+Double.MIN_VALUE+"至"+Double.MAX_VALUE);
System.out.println("char的表示范围从"+'\u0000'+"至"+'\uffff');
System.out.println("boolean的表示范围从"+Boolean.FALSE+"至"+Boolean.TRUE);
}
Java中的默认类型:整数类型是 int 、浮点类型是 double
//在代码 中使用直接量 的 一些 注意点
int i=100; //整数的直接量的 类型就是int
short s=100; //这里 执行了 自动类型转换,在赋值前 把int 转换成short
short s1=(short)9999;// 可能会发生 数据溢出
long l=100; //也执行了 自动类型转换,而且不会损失数据
long l2=233333334324; //为什么表示不了. 该数 超过了 int的表示范围,需要后面加L明确的表示它是Long类型
float f=2.5; //为什么有错误。 小数的直接量属于double类型,所以需要在后面加上F明确的表示它是Float类型
double d=2.5;
//大转小 会自动的类型转换 ,小转大 会报错 需要 强制类型转换 ,
char c='*';
int ic=c; //为什么可以这样做。字符类型内部表示为一份两字节的整数,这种赋值没有问题
char c2=12; //数字赋值给字符,只要数字在字符的表示范围内,就没问题。
似乎 代码块 不能把错误表示出来,下面 有截图。
自动类型转换:把表示范围小的数据转换为表示范围大的数据,java采用的是自动类型转换,这种情况不需要在表达式中明确的指出结果类型。
long result; int c1=2,c2=4; result=c1+c2;
这里 int 类型 c1和c2可以直接自动类型转换成 标示范围更大的long类型。
八大类型从小至大的排列关系: byte short int long float double
char
int result; long c1=2; result=c1;
这里的 long类型 想要给 int 赋值 就会 报错,因为long的表示范围是大于int的,把long类型值直接赋给int类型会有溢出的风险。
这是 软件自身的 为你可能的错误进行的 报错提示,但是这种提示也不是万能、什么时候都会出现的。
比如
//溢出判断
int result=2147483647+2147483647+2147483647+2147483647;
int test;
test=result;
System.out.println(test);
在上方的 代码中,int 类型的result变量已经承载了远超int范围大小的数值,并且输出时,发生溢出,但是,并没有报错提示。
强制类型转换,如果把表示范围大的类型数据转换为表示范围小的类型的数据,必须进行强制类型转换。
强制类型转换的语法:目标类型变量=(目标类型)源类型变量.
long l=10; int i=5 i=(int)l;
当然 强制类型转换 也是有可能会发生 溢出的。
注意;自动类型转换会发生溢出吗?会的,而且编译器不报错。
强制类型转换会发生溢出吗?会的,但是编译器会提前报错。
Java中为什么给float类型变量赋值需要加F,而给byte、short赋值的时候却不需要呢?
JVM规范中所说,并没有说float,int,byte等占多少个字节,而是真正的有效位是多少。比如byte的有效位是1个字节,也就是-128到127。使用Java编程的时候,就只能用byte表示-128到127之间的数,而真正JVM实现,一般byte还是占用和int一样大小:4个字节。
也就说在JVM看来,short,byte,int都是同一个东西。
这也就解释了为什么byte,short使用int字面量赋值的时候会不用强制转型。
在这里插入代码描述
short a=3;
byte b=2;
因为编译器在编译的只需要根据字面值3,字面值2来确定是否超过有效值即可,并不用做深入的检查,因为他们在JVM存在的类型也是一样的。
在这里插入图片描述
byte b=128;//error
同时在通过JVM在操作byte,short,int都是用的相同的指令:iconst,bipush等也能证明。
然而double和float在JVM中存储是不一样的。
System.out.println(3.2f==3.2d);//false
因此在使用double给float赋值的时候,会报错的。
short s1=1,s2=2,s3=3;
s3=s1+s2; //报错
还有
char s1=1,s2=2,s3=3;
s3=s1+s2; //报错
还有
byte s1=1,s2=2,s3=3;
s3=s1+s2; //报错
一些原因已经被指出。例如,事实上“…(几乎)所有关于byte,short的操作都会将这些原语提升为int”。然而,下一个明显的问题是:为什么这些类型被提升为int?
因此,更深入一层:答案可能仅仅与Java虚拟机指令集有关。正如Java虚拟机规范中的表所总结的那样,所有的整数运算,如加法、除法等,只适用于int和long类型,而不适用于较小的类型。
(顺便说一句:较小的类型(byte和short)基本上只用于数组。像new byte[1000]这样的数组需要1000个字节,像new int[1000]这样的数组需要4000个字节)
当然,现在有人可以说“……下一个明显的问题是:为什么这些指令只提供给int(和long)。
上面提到的JVM规范中提到了一个原因:
如果每个类型化指令都支持Java虚拟机的所有运行时数据类型,那么将有比用字节表示更多的指令
另外,Java虚拟机可以看作是一个真实处理器的抽象。为小型型号引入专用的算术逻辑单元是不值得的:它需要额外的晶体管,但它仍然只能在一个时钟周期内执行一个加法运算。JVM设计时的主流架构是32位,正好适合32位int(涉及64位长值的操作作为特殊情况实现)。
(注意:最后一段有点过于简单,考虑到可能的矢量化等,但应该给出基本思想,而不要深入研究处理器设计主题)
编辑:一个简短的附录,集中在问题中的例子上,但从更一般的意义上讲:人们还可以问,使用较小的类型存储字段是否有益。例如,有人可能认为可以通过存储来保存内存日历日作为一个字节。但在这里,Java类文件格式发挥了作用:类文件中的所有字段至少占据一个“slot”,其大小为一个int(32位)。(“宽”字段,双字段和长字段,占据两个插槽)。所以显式地将字段声明为short或byte也不会节省任何内存。
有什么不懂的,建议直接看官方文档
https://docs.oracle.com/javase/specs/index.html