java自动类型转化顺序-java long int自动转化
Java基础语法Java规范
image.png
Java字节码
java程序是以".java"为扩展名,当我们编写完java程序后,要执行程序需要经过两个阶段:编译和运行。
编译器
执行编译程序的称为编译器,java将java源文件编译成为字节码(bytecode)。字节码是高度优化的指令集合,但是字节码并不能直接被计算机所执行,这些指令只有java运行时系统执行(又称Java虚拟机,Java Vitual Machine)。
在Java中,源文件正式名称是编译单元(compilation unit),源文件是包含一个或多个类的定义的文本文件,文本文件以.java作为扩展名。源文件中的主类需要与源文件名称一致,即一个源文件有且只有一个主类,这有利于维护和组织程序。
将java程序编译成字节码文件,解决了两方面问题:跨平台和安全性。将java程序编译成统一的字节码文件,然后针对于不同的操作系统、硬件去实现Java虚拟机,这样只要给定的系统有运行时包就可以执行java程序,有效的解决了跨平台问题。因为JVM控制程序的执行,所以能够防止程序对所在的系统产生负面作用。
虽然java程序被设计为解释性语言,但是为了提供性能,也可以将字节码编译为本机代码。HotSpot为字节码提供了即时编译器(Just-Time,JIT),如果JVM中包含JIT编译器,就可以将一部分代码实时编译为机器可执行代码。
通过javac命令执行java编译器,会生成HelloWorld.class字节码文件。需要注意,源文件中如果包含多个类,编译后每个类都会生成一个以类名为名称,以.class结尾的字节码文件。
javac HelloWorld.java
解释器
Java编译器生成的字节码文件并不能直接被机器执行,需要通过JVM将字节码文件解释为机器可以识别的代码,然后才可以执行。
通过java命令运行程序,并且指定要执行的主类名称。Java会自动搜索包含该类名称且扩展名为.class的文件,如果找到就会执行指定类中的代码。
java HelloWorld
Java关键特性
java具有简单性、安全性、可移植性、面向对象、健壮性、多线程、体系结构中立、解释执行、高性能、分布式、动态性的特点。
编程范式
程序构造目前有两大范式,即:面向过程编程(process-oriented programming)和面向对象编程(object-oriented programming)。面向过程编程是围绕着“正在发生什么”进行编写,这种方式是将程序描述为一系列线性步骤,是将代码作用于数据之上。随着程序规模的不断增长,面向过程编程难以管理复杂、庞大的程序,这时就发明了第二种范式。面向对象编程是围绕着“将影响谁”,它是围绕着数据以及一系列精心设计的接口组织程序,即数据控制代码的访问。
抽象
面向对象的本质元素之一就是抽象,通过抽象管理复杂。而层次化分类是管理抽象的一种有力方式,将复杂系统的语义进行分层,将他们分解为多个更易于管理的部分。
OOP三原则
面向对象编程提供了用于帮助实现面向对象模型的机制,这些机制就是封装、继承、多态。
注释
Java提供三种注释:单行注释、多行注释、文档注释。
代码的组成
java程序是由空白符、标识符、字面值、关键字、运算符、注释和分隔符组成的。
数据类型
Java是一种强类型化语言,即每个变量、每个表达式具有一种类型,每种类型都是严格定义的。并且所有赋值,不管是显示的还是方法调用中通过参数传递的,都要进行类型兼容检查。
基本类型
Java定义了8中基本数据类型:byte、short、int、long、float、double、char、boolean。这8种基本类型可以分为:
尽管在java中一切皆对象,但是基本类型并不是对象,这样设计的原因是效率,如果将其设计为对象会极大地降低性能。这些基本类型在java中是有明确的范围的(c和c++会随着执行环境不同,其范围也不同),因为java需要具备可移植性。
整数类型
java中提供了四种整数类型:byte、short、int和longjava自动类型转化顺序,这些类型都有符号的,java不支持无符号的、只是正值的整数。
名称字节(byte)宽度(位)范围
byte
1
8
-128 ~ 127
shot
2
16
-32 768 ~ 32 767
int
4
32
-2 147 483 648 ~ 2 147 483 648
long
8
64
-9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
所有的整数值都是整型的字面值,字面值可以以二进制(JDK7开始支持)、八进制、十六进制表示。
int v1 = 123_456_789; //相当于x=123456789
int v2 = 0b10__0100__1010; //二进制
int v3 = 0735; //八进制
int v4 = 10; //十进制
int v5 = 0XF25; //十六进制
从JDK7开始,可以使用二进制指定整型字面值,使用0b或0B作为数值前缀。
从JDK7开始,整形字面值可以嵌入一个或多个下划线,嵌入下划线可以使阅读很大的整数时更容易。下划线只能用于分隔数字,不能位于字面值得开头和结尾,并且可以使用连续的多个下划线。
浮点类型
浮点数也称为实数,当计算需要小数精度的表达式时使用。java实现了IEEE-754标准集的浮点类型和运算符。float为单精度类型,double为双精度类型。
名称字节宽度(位)大致范围
float
4
32
1.4e-045 ~ 3.4e+038
double
8
64
4.9e-324 ~ 1.8e+308
浮点字面值可以使用标准计数法或科学计数法表示,如2.32、2.3E5、3.14e-3,E或e表示10的幂。java中浮点字面值默认为double,如果要制定为float,需要在常量后面添加F或f。
字符类型
用于存储字符集的类型是char,java所表示的字符集是Unicode字符集。Unicode定义了一个完全国际化的字符集,Unicode是数十种字符集的统一体,能够表示人类语言中的所有字符(至少目前是)。Unicode需要16位宽,所以char类型也需要16位宽。
ASCII标准字符集的范围是0~127,扩展的ISO-Latin-1范围是0~255。
名称字节宽度(位)大致范围
char
2
16
0 ~ 65536
对于char类型既可以直接赋值字符,也可以赋值字符所在Unicode中的所在位置。
char a = 88; //代表'X'
char b = 'Y';
在java正式规范中,char被当做整数类型。然而在实际应用中,主要将其用来表示Unicode字符,所以将其单独分为一类。
字符类型字面值可以使用位于一对单引号中的字符表示,对于那些不可见的字符可以使用转义字符。也可以使用八进制或十六进制表示,对于八进制使用反斜杠后加三位数字表示,对于十六进制以 "\u"后加4位十六进制数,比如 '\121'、'\ua432'。
char v7 = 22;
char v8 = 'a';
char v9 = '\121';
char v10 = '\ua245';
转义序列描述
\ddd
八进制字符(ddd)
\uxxxx
十六进制Unicode序列(xxxx)
\ '
单引号
\"
双引号
\\
反斜线
\r
回车符
\n
换行符
\f
换页符
\t
制表符
\b
回格符
布尔类型
在java中布尔类型用于表示逻辑值,它只能为true或false,所以它只需要一个字节即可。
布尔字面值只有两个逻辑值:true和false。true和false不能转换为任何数字,也就是说 boolean a = 1是不支持的。
变量
在Java中,变量是基本存储单元。定义变量通过标识符、类型以及可选的初始化器来定义。所有变量都有作用域,作用域定义了变量的可见性和生命周期。
type identifier = [value][,indentifier [= value] ...];
变量可以在定义的时候初始化,也可以动态的初始化。
double v11 = 1.1;
double v12;
for(int i=0; i<10 ;i++) {
v12 = Math.sqrt( i * i );
}
变量作用域
Java允许在任何代码块中定义变量,代码块定义了变量的作用域,每个变量的作用域都是在代码块中的。作用域决定了变量的可见性和生存周期。
尽管java通过代码块来划分作用域,在实际使用中人们经常将变量定义在类中的称为类变量或全局变量,定义在方法中的称为方法变量或局部变量。
类变量
类变量定义在类体内部,方法体外部。类变量可以定义在类中的任何位置,整个类都可以使用。类变量可以不初始化值直接使用,这样会根据数据类型使用类型默认值。
方法变量
方法中定义的变量和方法内代码块定义的变量具有相同特性,它们的作用域都是从定义位置开始到代码块结束(和类变量不同),都需要先初始化在使用。
public static void main(String[] args){
double v11;
//double v13 = v11 + 1; //需要先初始化
for(int i=0; i<10 ;i++) {
double v12 = Math.sqrt( i * i );
}
//System.out.println(v12); //v12的作用域在for循环内
}
注意:方法中定义的变量,内层代码块中不允许与外层代码块定义相同的变量名称
类型转换
Java类型转换分为自动类型转换和强制类型转换,例如int类型总能自动转换为long类型,但是double类型却不能自动转换为int类型,所以需要强制类型转换(cast)。
自动类型转换
自动类型转换也成扩展转换(widening conversion),只要满足以下两个条件就会发生自动转换。
两种类型是兼容的目标类型大于源类型
对于自动扩展类型,数值类型(整数和浮点型)是相互兼容的,但是数值类型不能和char或boolean类型的自动转换,char和boolean相互也是不兼容的。
强制类型转换
对于相互之间不兼容的类型,或目标类型小于源类型,就需要使用强制类型转换了。强制类型也称为缩小转换(narrowing conversion),因为显示的将数值变的更小。
//(target-type) value; 强制类型转换
int v14 = 257;
byte v15 = (byte) v14;
对于整数类型,当进行强制类型转换后,如果源类型超出了目标类型,将会以数值除以目标类型范围取模。比如,上面将int类型强制转换为byte类型,并且超过了byte类型范围,则 v14/256(byte的范围),结果为1。
对于浮点类型,如果将浮点类型转换为整数类型时,则会进行截尾,即把小数点截掉。
表达式中自动类型提升
除了赋值外,在使用表达式时也可能发生某些类型转换。
有时我们会想如果我们变量本身就在byte范围就把他定义为byte类型,这样可以节省空间、提升效率。但其实这是错误的,因为在表达式中byte、char、short需要转换为int类型。
自动类型提升,有时会引起难以理解的编译错误,比如下面的例子:
byte b = 50;
b = b * 2;
会提示编译错误,因为b * 2会提升为int类型,但是int类型无法自动转换为byte类型,所以需要强制类型转换,b = (byte) b * 2。
数组
数组即一组类型相同的变量,可以创建任意类型、任意维(一维或多维)的数组,访问数组元素是通过数组下标索引来访问的。
创建数组:
//定义规范
type var-name[] = new type[n];
type[] var-name = new type[n];
int[] v16 = new int[10];
int v17[] = new int[19];
如果只声明数组,数组实际并没有创建物理存储地址,需要使用new关键词为数组指定数组长度。数组定义完成后,会为其设置默认值,对于数值类型会被自动初始化为0、布尔类型会被初始化为false、引用类型会被初始化为null。
在定义数组时候,可以直接为数组初始化:
int[] v18 = {1,2,3};
在Java中多维数组实际上就是数组的数组,java允许你只为第一维指定长度,其它维度长度可以自行指定,所以长度可以不同。
int[][] v19 = new int[10][10];
int[][] v20 = new int[10][];
v20[0] = new int[1];
v20[1] = new int[2];
v20[3] = new int[3];
运算符
Java提供了丰富的运算符,可以将其分为4组:算术运算符、关系运算符、逻辑运算符和位运算符。另外还有比较特殊的类型比较运算符instanceof和箭头运算符->。
算术运算符
算术运算符的操作数必须是数值类型,不可以为boolean类型使用算术运算符,但是可以为char类型使用算术运算符,因为char的本质是int的子集。
算术运算符包括:+、-、*、/、%、+=、-=、*=、/=、%=、++、--
。其中+=这类叫做赋值复合运算符,a++相当于a = a + 1,复合运算符不仅使用方便,而且运行效率也高。
使用除法运算符,对于整数其结果不会包含小数。
对于自增运算符++、--java自动类型转化顺序,如果单独使用a++和++a没有区别,但是如果放到表达式中c = a++和c = ++a是不同的,c = a++ 会现将a赋值给c之后在进行自增,而c = ++a是将a+1执行之后再赋值给c。
关系运算符
关系运算符用来判断一个操作数与另一个操作数之间的关系,关系运算符的结果为布尔值。
关系运算符包括:==、!=、>、>=、
右移,将数值中所有位向右移动指定的次数,左侧补0(不一致为0,填充符号位)。右移一位相当于除2
64 >> 2 = 16
>
右移零填充,又称为无符号右移,即不会根据符号位填充左侧的值,一直都是0
a = -1
a = a >>> 24
115387295596115387295596 11111111 >>> 24 = 01538729559600153872955960 11111111
&=
按位与并赋值
a = a&2
|=
按位或并赋值
a = a|2
^=
按位异或并赋值
a= a^2
>>=
右移并赋值
a = a >> 1
=
右移零填充并赋值
a = a>>> 1
通过左右移位可以实现高效的乘除2操作。
当进行右移时右移后的顶部(最左边)位使用右移前的最高位(最左边的第一位,符号位)进行填充,这称为符号扩展,该特性能够保留负数的符号。比如:
11111000 -8
-8 >> 1
11111100 -4
对于-1无论怎么右移,最后的结果一直都是-1。
还需要记住,对于byte、short都会自动提升为int类型。
赋值运算符
赋值运算符使用单个"="号,
形式:
var = expression
赋值运算符允许创建赋值链,将一组变量设置相同值。比如 x = y = z = 10
表达式中的运算符优先级影响着其表达式的结果,Java运算符优先级从高到低:
自增运算符(++、--)
算术运算符(*、/、%、+、-)
移位运算符(>>、>>>、=、