首页 > 代码库 > java基础问题解答

java基础问题解答

Java学习中的问题

 

枚举类型:

下面是一段源程序代码:

package Demo;

 

public class Enum {

 

public static void main(String[] args) {

Size s=Size.SMALL;

Size t=Size.LARGE;

//s和t引用同一个对象?

System.out.println(s==t);  //

//是原始数据类型吗?

System.out.println(s.getClass().isPrimitive());

//从字符串中转换

Size u=Size.valueOf("SMALL");

System.out.println(s==u);  //true

//列出它的所有值

for(Size value:Size.values()){

System.out.println(value);

}

}

 

}

 enum Size{SMALL,MEDIUM,LARGE};

 

运行结果:技术分享

结果分析:st印的不是同一个对象,s引用Size.SMALL,t引用Size.LARGE,故输出的第一个结果是false,由于s不是原始数据类型,所以第二个运行结果也是falseu通过字符串转换,转换成和s相同类型的数据,所以第三个是true,最后是输出size里面的所有数据。

 

结论:枚举类型是引用类型!

枚举不属于原始数据类型,它的每个具体值都引用一个特定的对象。相同的值则引用同一个对象。

可以使用==”和equals()方法直接比对枚举变量的值,换句话说,对于枚举类型的变量,“==”和equals()方法执行的结果是等价的。

 

输出时类型问题:

以下代码的输出结果是什么?

int X=100;

int Y=200;

System.out.println("X+Y="+X+Y);

System.out.println(X+Y+"=X+Y");

为什么会有这样的输出结果?

运行结果截图:技术分享

 

 

分析:第一个中的XY没有进行相加运算,原因是“X+Y=”是String类型的加号联结的是相同类型的,会把后面的XY自动转化为String类型的,故不再进行加法运算,第二个一开始的XYint型的,可以进行加法运算,股输出结果如上。

 

三变量的作用域:

 

每个变量都有一个“有效”的区域(称为“作用域”),出了这个区域,变量将不再有效。

请看左边的示例代码,输出结果是什么?

 技术分享

每个变量都有一个“有效”的区域(称为“作用域”),出了这个区域,变量将不再有效,同名的变量在指定的范围内有自动屏蔽的原则。即局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。

 

输出结果是:2。显然可以看出value=http://www.mamicode.com/1的是全局变量,而value=http://www.mamicode.com/2的是全局变量

四:反码,补码,原码的理解:

  在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念。

1、机器数

  一个数在计算机中的二进制表示形式叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011

那么,这里的 00000011 10000011 就是机器数。

2、真值

  因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值13110000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +11000 0001的真值 = 000 0001 = 1

对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.

1. 原码

  原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

[+1]= 0000 0001

[-1]= 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式.

2. 反码

  反码的表示方法是:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]= [00000001]

[-1] = [10000001]= [11111110]

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

3. 补码

  补码的表示方法是:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]= [00000001]= [00000001]

[-1] = [10000001]= [11111110]= [11111111]

对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.

五:Java中数据类型的转换规则:
基本数据类型的转换是指由系统根据转换规则自动完成,不需要程序员明确地声明不同数据类型之间的转换。转换在编译器执行,而不是等到运行期再执行。

 

整型: byte8,short16,int(32), long64

浮点型: float(32), double(64)

具体规则:

1)布尔型和其它基本数据类型之间不能相互转换;

2byte型可以转换为shortintlongfloatdouble

3short可转换为intlongfloatdouble

4char可转换为intlongfloatdouble

5int可转换为longfloatdouble

6long可转换为floatdouble

7float可转换为double

图示:

 技术分享

注:(其中除了float类型转换为double类型为无精度损失,其他类型转换为double类型都是有精度损失)

也就是说,只能有取值窄的范围向宽范围转换,反之则不行。

 

 

问题:为什么double类型的数值进行运算得不到“数学上精确”的结果?

  答案:这个涉及到二进制与十进制的转换问题。N进制可以理解为:数值×基数的幂,例如我们熟悉的十进制数123.4=1×10²+2×10+3×(100次幂)+4×(10-1次幂);其它进制的也是同理,例如二进制数11.01=1×2+1×(20次幂)+0+1×(2-2次幂)=十进制的3.25

double类型的数值占用64bit,即64个二进制数,除去最高位表示正负符号的位,在最低位上一定会与实际数据存在误差(除非实际数据恰好是2n次方)。

举个例子来说,比如要用4bit来表示小数3.26,从高到低位依次对应21,0,-1,-2次幂,根据最上面的分析,应当在二进制数11.01(对应十进制的3.25)11.10(对应十进制的3.5)之间选择。

简单来说就是我们给出的数值,在大多数情况下需要比64bit更多的位数才能准确表示出来(甚至是需要无穷多位),而double类型的数值只有64bit,后面舍去的位数一定会带来误差,无法得到“数学上精确”的结果。

 

java基础问题解答