java学习中的一些疑惑解答

Tory49R 8年前
   <h2><strong>一、java中的枚举类型:</strong></h2>    <p>在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场,下面的一段代码来说明枚举类型的特点和用法:</p>    <pre>  <code class="language-java">public class EnumTest {        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};  </code></pre>    <p>从运行结果来看</p>    <p>(1)枚举类型中的元素不是一个对象,枚举是一个数据集,它的每个具体值都引用一个特定的对象。相同的值则引用同一个对象。</p>    <p>(2)枚举类型是一种新的数据类型,并非是原始数据类型</p>    <p>(3)枚举类型中的元素可以转换为字符串类型,并且里面的所以元素可以列举出来</p>    <h2><strong>二、反码,补码,原码的理解:</strong></h2>    <p>在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念。</p>    <p>1、机器数</p>    <p>一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.</p>    <p>比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。</p>    <p>那么,这里的 00000011 和 10000011 就是机器数。</p>    <p>2、真值</p>    <p>因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。</p>    <p>例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1</p>    <p>对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.</p>    <p>1. 原码</p>    <p>原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:</p>    <p>[+1]原 = 0000 0001</p>    <p>[-1]原 = 1000 0001</p>    <p>第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:</p>    <p>[1111 1111 , 0111 1111]</p>    <p>即</p>    <p>[-127 , 127]</p>    <p>原码是人脑最容易理解和计算的表示方式.</p>    <p>2. 反码</p>    <p>反码的表示方法是:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.</p>    <p>[+1] = [00000001]原 = [00000001]反</p>    <p>[-1] = [10000001]原 = [11111110]反</p>    <p>可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.</p>    <p>3. 补码</p>    <p>补码的表示方法是:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)</p>    <p>[+1] = [00000001]原 = [00000001]反 = [00000001]补</p>    <p>[-1] = [10000001]原 = [11111110]反 = [11111111]补</p>    <p>对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.</p>    <h2><strong>三、Java中同名变量的屏蔽原则:</strong></h2>    <p>每个变量都有一个“有效”的区域(称为“作用域”),出了这个区域,变量将不再有效,同名的变量在指定的范围内有自动屏蔽的原则。即局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。下面以一段程序来进行说明:</p>    <pre>  <code class="language-java">public class Test {      private static int value = 1;      public static void main(String[] args) {          int value = 2;          System.out.println(value);  </code></pre>    <p>输出结果是:2。显然可以看出value=1的是全局变量,而value=2的是全局变量。</p>    <h2><strong>四、Java中数据类型的转换规则:</strong></h2>    <p>基本数据类型的转换是指由系统根据转换规则自动完成,不需要程序员明确地声明不同数据类型之间的转换。转换在编译器执行,而不是等到运行期再执行。</p>    <p>具体规则:</p>    <p>(1)布尔型和其它基本数据类型之间不能相互转换;</p>    <p>(2)byte型可以转换为short、int、long、float和double;</p>    <p>(3)short可转换为int、long、float和double;</p>    <p>(4)char可转换为int、long、float和double;</p>    <p>(5)int可转换为long、float和double;</p>    <p>(6)long可转换为float和double;</p>    <p>(7)float可转换为double;</p>    <p>注:(其中除了float类型转换为double类型为无精度损失,其他类型转换为double类型都是有精度损失)</p>    <p>也就是说,只能有取值窄的范围向宽范围转换,反之则不行。</p>    <h2><strong>五、问题:为什么double类型的数值进行运算得不到“数学上精确”的结果?</strong></h2>    <p>答案:这个涉及到二进制与十进制的转换问题。N进制可以理解为:数值×基数的幂,例如我们熟悉的十进制数123.4=1×10²+2×10+3×(10的0次幂)+4×(10的-1次幂);其它进制的也是同理,例如二进制数11.01=1×2+1×(2的0次幂)+0+1×(2的-2次幂)=十进制的3.25。</p>    <p>double类型的数值占用64bit,即64个二进制数,除去最高位表示正负符号的位,在最低位上一定会与实际数据存在误差(除非实际数据恰好是2的n次方)。</p>    <p>举个例子来说,比如要用4bit来表示小数3.26,从高到低位依次对应2的1,0,-1,-2次幂,根据最上面的分析,应当在二进制数11.01(对应十进制的3.25)和11.10(对应十进制的3.5)之间选择。</p>    <p>简单来说就是我们给出的数值,在大多数情况下需要比64bit更多的位数才能准确表示出来(甚至是需要无穷多位),而double类型的数值只有64bit,后面舍去的位数一定会带来误差,无法得到“数学上精确”的结果。</p>    <p>六、Java中输出的加号连接符的使用:</p>    <p>首先看看下面的代码输出结果:</p>    <pre>  <code class="language-java">public static void main(String[] args) {      int X=100;      int Y=200;      System.out.println("X+Y="+X+Y);      System.out.println(X+Y+"=X+Y");   }  </code></pre>    <p>输出结果为:</p>    <p><img src="https://simg.open-open.com/show/6bf2157ec7c570ea4645f45cedd5b6cb.png"></p>    <p>从输出结果我们可以看出只有与 ” ” 字符串直接相连的后面 “+” 加号才会都被定义成连接符。</p>    <p>System.out.println(“X+Y=”+X+Y); 这条输出语句打印的内容 ”  ” 字符串后面的两个 “+” 加号都会被定义成连接符,所以是100200而不是300.</p>    <p>System.out.println(X+Y+”=X+Y”); 而这条输出语句打印的内容前面的X+Y会先运算的,因为前面的 “+” 加号还是运算符,Y后面的+加号才是连接符。只有与 ” ” 字符串直接相连时后面 “+” 加号才会都被定义成连接符。</p>    <p> </p>    <p>来自:http://www.58maisui.com/2016/10/08/673/</p>    <p> </p>