程序可以模拟万物变量变量是程序基本组成单位变量的基本要素类型、名称、值。类型决定了变量的取值范围值决定了变量的空间大小。变量表示内存中一个数据存储区域该区域有自己的名称变量名和类型数据类型。不同类型的变量占用的空间大小不同具体表现为存储值的范围。该区域的数据可以在同一类型的范围内不断变化。变量名的长度基本上没有限制 尽管$ 是一个合法的Java 字符 但不要在你自己的代码中使用这个字符。它只用在Java 编译器或其他工具生成的名字中。java 中变量需要先声明变量在同一个作用域内不能重名在Java中变量的声明尽可能地靠近变量第一次使用的地方这是一种良好的程序编写风格。在Java中利用关键字final指示常量。在Java中经常希望某个常量可以在一个类中的多个方法中使用通常将这些常量称为类常量。可以使用关键字static final设置一个类常量。 的使用表达式左右两边都是数值类型时则做的是加法运算。表达式左右两边有一方为字符串则做的拼接运算。数据类型java中每一种数据都定义了明确的数据类型在内存中分配了不同大小的内存空间。所以说java是强类型语言。基本数据类型是CPU可以直接进行运算的类型。这些基本数据类型有什么区别呢计算机内存的最小存储单元是字节byte一个字节就是一个8位二进制数即8个bit。它的二进制表示范围从00000000~11111111换算成十进制是0~255换算成十六进制是00~ff。内存单元从0开始编号称为内存地址。每个内存单元可以看作一间房间内存地址就是门牌号。一个字节是1byte1024字节是1K1024K是1M1024M是1G1024G是1T。一个拥有4T内存的计算机的字节数量就是4T 4 x 1024G 4 x 1024 x 1024M 4 x 1024 x 1024 x 1024K 4 x 1024 x 1024 x 1024 x 1024 4398046511104不同的数据类型占用的字节数不一样。我们看一下Java基本数据类型占用的字节数byte类型恰好就是一个字节而long和double需要8个字节。数值类型整形的类型byte short int long大小是从1开始2倍自增java各整数类型有固定的范围和字段长度不受具体的操作系统的影响。java的整型常量默认为int 型声明long型常量必须后加’l’或“L”。bit 计算机中最小的存储单位byte:计算机中基本存储单元1 byte 8 bit。short、int、long在计算机中存储地位补0。赋值时只要常量或变量(这里指的是变量的范围而不是变量的值)的类型范围在被赋值的变量的范围内都可以进行赋值publicclassVarDetail{publicstaticvoidmain(String[]args){inta10;//int b 20L; //会抛异常longc10;System.out.println(c);}}整数的数值表示不仅是精确的而且整数运算永远是精确的即使是除法也是精确的不会像浮点型那样会有精度损失两个整数相除只能得到结果的整数部分。面试题如下代码执行test()函数后屏幕打印结果为publicclassTest2{publicvoidadd(Byteb){bb;}publicvoidtest(){Bytea127;Byteb127;add(a);System.out.print(a );add(b);System.out.print(b);}}答案-128 127。解析a127执行a时发生拆箱运算并进行前置自增1271溢出为-128byte 溢出取模再装箱回Byte因此a变为-128。add(a)中的方法体b b对形参b先自增再把旧值赋回等价于无效操作且按值传递不会影响实参所以a仍为-128。b127执行add(b)也无效b仍为127。浮点float double大小从4开始2倍自增说明:关于浮点数在机器中存放形式的简单说明浮点数符号位指数位尾数位。浮点数运算和整数运算相比不能做位运算和移位运算。java的浮点型常量默认为double型声明float型常量必须加f或F浮点型常量表示形式有两种:十进制5.12512.0f.512(意思本来是0.512这里省略了0)3.15d科学计数法5.12e25.12E-2在不知道使用任何浮点类型的情况下使用double类型。浮点数使用陷阱有些浮点数在计算中无法精确表示。例如浮点数0.1在计算机中就无法精确表示因为十进制的0.1换算成二进制是一个无限循环小数很显然无论使用float还是double都只能存储一个0.1的近似值。但是0.5这个浮点数又可以精确地表示。浮点型在运算的时候赋值给变量时结果和预想的会有很小的误差, 原因:无法精确表示的会存储为一个近似值。publicclassFloatDetail{publicstaticvoidmain(String[]args){doubled13.21;System.out.println(d1);doubled30.1;System.out.println(d3);// 0.1doubled25.4-5.3;// 0.10000000000000053System.out.println(d2);doublenum82.7;doublenum98.1/3;System.out.println(num8);//2.7System.out.println(num9);//2.6999999999999997}}所以两个浮点数在比较时候就要小心。所以这里当遇到精度数据比较时候我们可以这样写:publicclassFloatDetail{publicstaticvoidmain(String[]args){doublenum82.7;doublenum98.1/3;System.out.println(num8);System.out.println(num9);if(num8num9){System.out.println(num8和num9相等);}System.out.println(Math.abs(num8-num9));if(Math.abs(num8-num9)0.00001){System.out.println(num8和num9相差很小的时候几乎不影响业务。就认为num8和num9相等);}}}整数运算在除数为0时会报错而浮点数运算在除数为0时不会报错但会返回几个特殊值NaN表示Not a NumberInfinity表示无穷大-Infinity表示负无穷大浮点数值不适用于无法接受舍入误差的金融计算中。例如命令System.out.println(2.0-1.1)将打印出0.8999999999999999而不是人们想象的0.9。这种舍入误差的主要原因是浮点数值采用二进制系统表示而在二进制系统中无法精确地表示分数1/10。这就好像十进制无法精确地表示分数1/3一样。如果在数值计算中不允许有任何舍入误差就应该使用**BigDecimal类**。整数被0除将会产生一个异常而浮点数被0除将会得到无穷大或NaN结果。对于浮点数运算来说,如果想采用严格模式进行运算需要关键字strictfp,严格模式有可能导致精度溢出。默认情况下都会采用扩展精度。字符类型字符类型可以表示单个字符字符类型的是char, 大小为两个字节可以存放汉字使用单引号引起来。字符类型可以直接赋值给一个整数常量。字符使用细节java中char的本质是一个整数在输出时是**unicode码对应的字符**https://tool.chinaz.com/tools/unicode.aspx?qq-pf-topcqq.group既然char的本质是一个整数char类型的运行就相当于unicode码整数的运算。publicclassCharDetail{publicstaticvoidmain(String[]args){System.out.println(a10);// 输出107 这里a字符会先转化成unicode的数字然后与10相加System.out.println(是10);// 26169}}转义序列\u还可以出现在加引号的字符常量或字符串之外例如方法参数 a(\u2922), 这样写法一般用于逆向中可以使编码混淆.Unicode 转义序列会在解析代码之前得到处理。字符类型的本质字符型数据在计算机中读取和存储需要进行字符--码值--二进制之间的转换存储过程‘a’码值97二进制读取过程: 二进制码值97‘a’Java中的“字母”和“数字”表示的范围更大。字母包括’A’ ~ ‘Z’、‘a’ ~ ‘z’、‘_’、‘$’或在某种语言中表示字母的任何Unicode字符。同样数字包括’0’~9’和在某种语言中表示数字的任何Unicode字符。char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示而辅助字符需要一对代码单元表示。码点(codepoint)是指与一个编码表中的某个字符对应的代码值。在Unicode标准中码点采用十六进制书写并加上前缀U例如U0041就是拉丁字母A的码点。UTF-16编码采用不同长度的编码表示所有Unicode码点。在基本的多语言级别中每个字符用16位表示通常被称为代码单元(code unit);而辅助字符采用一对连续的代码单元。要想得到实际的长度即码点数量可以调用:int cpCount greeting.codePointCount(0, greeting.length();调用s.charAt(n)将返回位置n的代码单元n介于0~s.length()-1之间。例如:char first greeting.charAt(0); // first is Hchar last greeting.charAt(4); // last is o要想得到第i个码点应该使用下列语句int index greeting.offsetByCodePoints(0i);int cp greeting.codePointAt(index);编码因为计算机只能处理数字如果要处理文本就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特bit作为一个字节byte所以一个字节能表示的最大的整数就是255二进制11111111十进制255如果要表示更大的整数就必须用更多的字节。比如两个字节可以表示的最大整数是655354个字节可以表示的最大整数是4294967295。由于计算机是美国人发明的因此最早只有127个字符被编码到计算机里也就是大小写英文字母、数字和一些符号这个编码表被称为ASCII编码比如大写字母A的编码是65小写字母z的编码是122。但是要处理中文显然一个字节是不够的至少需要两个字节而且还不能和ASCII编码冲突所以中国制定了GB2312编码用来把中文编进去。你可以想得到的是全世界有上百种语言日本把日文编到Shift_JIS里韩国把韩文编到Euc-kr里各国有各国的标准就会不可避免地出现冲突结果就是在多语言混合的文本中显示出来会有乱码。因此Unicode字符集应运而生。Unicode把所有语言都统一到一套编码里这样就不会再有乱码问题了。Unicode标准也在不断发展但最常用的是UCS-16编码用两个字节表示一个字符如果要用到非常偏僻的字符就需要4个字节。现代操作系统和大多数编程语言都直接支持Unicode。现在捋一捋ASCII编码和Unicode编码的区别ASCII编码是1个字节而Unicode编码通常是2个字节。字母A用ASCII编码是十进制的65二进制的01000001字符0用ASCII编码是十进制的48二进制的00110000注意字符0和整数0是不同的汉字中已经超出了ASCII编码的范围用Unicode编码是十进制的20013二进制的01001110 00101101。你可以猜测如果把ASCII编码的A用Unicode编码只需要在前面补0就可以因此A的Unicode编码是00000000 01000001。新的问题又出现了如果统一成Unicode编码乱码问题从此消失了。但是如果你写的文本基本上全部是英文的话用Unicode编码比ASCII编码需要多一倍的存储空间在存储和传输上就十分不划算。所以本着节约的精神又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节常用的英文字母被编码成1个字节汉字通常是3个字节只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符用UTF-8编码就能节省空间字符ASCIIUnicodeUTF-8A0100000100000000 0100000101000001中x01001110 0010110111100100 10111000 10101101从上面的表格还可以发现UTF-8编码有一个额外的好处就是ASCII编码实际上可以被看成是UTF-8编码的一部分所以大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。小结:ASCII编码编码表 用一个字节表示一个128个字符。实际上一个字节可以表示256个字符但是只用了128个。Unicode(UCS-16) 用两个字节表示一个字符(如果要用到非常偏僻的字符就需要4个字节)UTF-8编码: 把一个Unicode字符根据不同的数字大小编码成1-6个字节常用的英文字母被编码成1个字节汉字通常是3个字节(可以表示更多的汉字)只有很生僻的字符才会被编码成4-6个字节。gbk gb2312表示的汉字比较少一般不用 big5(可以存储繁体字)。。。搞清楚了ASCII、Unicode和UTF-8的关系我们就可以总结一下现在计算机系统通用的字符编码工作方式在计算机内存中统一使用Unicode编码当需要保存到硬盘或者需要传输的时候就转换为UTF-8编码。用记事本编辑的时候从文件读取的UTF-8字符被转换为Unicode字符到内存里编辑完成后保存的时候再把Unicode转换为UTF-8保存到文件浏览网页的时候服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器所以你看到很多网页的源码上会有类似meta charsetUTF-8 /的信息表示该网页正是用的UTF-8编码。布尔类型布尔类型 占用一个字节只允许表示true或false一般用于逻辑判断。布尔类型无法进行强制转换。Java语言对布尔类型的存储并没有做规定因为理论上存储布尔类型只需要1bit但是通常JVM内部会把boolean表示为4字节整数。自动转换和强制转换自动转换当java程序进行赋值或运算时精度小的类型自动转换为精度大的数据类型这个就是自动类型转换。一般遵循以下规则(低精度可以转换至高精度):这里注意long-float可能会产生精度溢出。使用细节多种类型的数据混合运算时系统首先会自动将所有数据转换成容量最大的那种数据类型然后进行计算。接受计算结果类型变量必须要和最大类型一样。floatd1n11.1;//这样写是错误的因为1.1默认是double, n1 1.1后也是double类型double类型不能直接赋值给float类型。doubled1n11.1;//正确floatd2n11.1f;//正确intn21.1//错误 会报错在常量赋值给变量的时编译器会先判断右边的常量是否定义在左边的变量的类型大小的范围内。如果在就可以先赋值前提要遵循自动转换图的前提下。如果是变量赋值时会直接使用变量的范围进行判断右边的变量范围必须在左边的范围内。byteb110;// byte 范围-128~127 10在范围内可以赋值。byteb2300;//没在范围内编译器就会报错。intn121;byteb3n1;//由于n1是int类型4字节b3是byte类型1字节。n1的类型没有在b3的类型范围内或者说n1容量大b3容量小所以这里是错误的byte,short类型与char类型之间不能相互转换, 但可以进行计算计算时精度提升到int(包括byte、short、char自身相互运算)。byteb110;charc1b1;//错误byte, short 类型与char 类型之间不能相互转换//..................byteb110;shorts115;shorts2s1b1;//错误: s1 b1 精度是int int类型赋值给short 高精度转低精度有可能精度丢失会报错chars315;shorts4s1s3;//错误: byte、short、char自身相互运算精度也会提升到int。int类型赋值给short 高精度转低精度有可能精度丢失会报错bool类型不参与自动转换这块跟php不一样。两个数进行运算如果两个操作数中有一个是double类型另一个操作数就会自动转换为double类型。否则如果其中一个操作数是float类型另一个操作数将会自动转换为float类型。否则如果其中一个操作数是long类型另一个操作数将会自动转换为long类型。否则两个操作数都将被转换为int类型。强制转换将精度大的类型手动转换为精度小的数据类型,使用是要加上强制转换符()。强制转换可能会造成精度丢失和数据溢出需要格外的注意对于业务允许的情况下可以进行强制转换。publicclassForceConvert{publicstaticvoidmain(String[]args){inti(int)1.9;System.out.println(i);//1 精度丢失intn123000;byteb1(byte)n1;System.out.println(b1);//-40 数据溢出}}使用细节强转符号只针对最近操作数有效往往使用小括号提升优先级。intn2(int)10*3.52*3.6;//报错因为结果是double类型 double赋值给int 高精度转低精度精度丢失intn2(int)(10*3.52*3.6);//正确 42警告:如果试图将一个数值从一种类型强制转换为另一种类型而又超出了目标类型的表示范围结果就会截断成一个完全不同的值。例如(byte)300的实际值为44。基本数据类型与字符串互转基本数据类型转换成String类型特别简单只需要基本数据类型 就可以了int n1 100; float f1 2.234f; String s1 n1 f1 ; //102.234 String s2 n1 f1; //1002.234字符类型转String 也可以使用 “”String 类型转换成基本数据类型则需要通过基本数据类型包装类调用parseXX方法既可。Strings3123;intnum1Integer.parseInt(s3);doublenum2Double.parseDouble(s3);floatnum3Float.parseFloat(s3);longnum4Long.parseLong(s3);shortnum5Short.parseShort(s3);bytenum6Byte.parseByte(s3);//注意:不能大于255booleannum7Boolean.parseBoolean(true);使用细节将String转换成基本数据类型时要确保String类型能够转换成有效的数据。所以如果格式不正确就会抛出异常(会在运行时候抛出)程序终止。比如“123可以转换成整数“hello”却不能。转化成基本类型时要注意转化后的基本类型范围比如Stringstr999;byteb1Byte.parseByte(str);System.out.println(b1);上述代码会抛出NumberFormatException异常因为转化后的数字范围已经超出了Byte的最大值。