`
kodak_zhou
  • 浏览: 136748 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java解惑读书笔记1

    博客分类:
  • java
阅读更多
1。奇偶判断,应该用i%2!=0为奇数来判断,因为当为负数的时候%2的结果可能会是-1,用i%2==1会出错。(i&1)!=0使用低位是否为1来判断是否奇偶。


2。小数精确计算。java中的float和double都是不太精确的,容易造成精度丢失,比如System.out.println(2.00-1.10);结果不是0.9而是0.8999999999999999。一次我们可以用long或者int来代替浮点数(比如0.9我们可以用200-110表示来计算,最后结果除以100.0F)。或者使用BigDecimal


3.int 相乘溢出!这个最常见了,在项目中经常出现多少天等于多少毫秒之类的,如果这样算long s =  25 * 24 * 3600 * 1000,最后s=-2134967296,怎么会溢出呢,原因是这几个都是整形,最大值是2147483647,所以25天就溢出了而24天是正常的,怎么办?把25改为25L即可,它会强制转化为long型再计算,如果我把1000改为1000L,像这样long s =  25 * 24 * 3600 * 1000L,可能会溢出吗?还是会,如果前面的数字超出整形就溢出,所以应该把左边的第一个数设置为long型。


4.字面常量,所以的字面常量都是int型,不管是10进制还是16进制,除非以L结尾表示他是long型。


5.窄数字拓展到宽数字的拓展。如果是char类型,一定是无符号拓展,因为char没有负数。其他的,如果之前是正数则无符号拓展,如果是负数则有符号拓展。记住这点即可。

6.这个和上面的相似。(byte)0x90 == 0x90 吗?不等于,因为左边的会被拓展成int,而byte这个是负数,会有符号拓展,最后结果是负数和0x90当然不相等,可以加一个掩码0xFF把前面的负数去除即可 (byte)0x90 & 0xFF == 0x90,

按位与0xFF的意思是只保留数字的低8位,高位按0处理。


7.三元表达式(:?)。讨论起表达式的值,a?b:c这样的,如果b或者c一个是int或者long字面常量,而另一个是char byte short等变量,则表达式类型为char byte short。如果没有一个是字面常量,则拓展为最宽的作为表达式类型。举例
Java代码 
char x = 'X'; 
int i = 65; 
System.out.println(true ? x : 65);// X 
System.out.println(false ? x : 65);// A。注意这里不是65 
System.out.println(true ? i : x);// 65 
System.out.println(false ? i : x);// 88。注意这里不是X 


8.+=符合运算。x+=i和x=x+i是不等效的,因为会涉及到类型的转化。如果x是窄的,i是宽的,x+=i编译不报错但结果可能会溢出,而x=x+i则编译不通过。所以尽量不要在复合运算左边用byte char short类型,容易溢出。举例。
Java代码 
int i=10033333; 
byte b = 12; 
//编译无措,结果会溢出 
b += i; 
//编译错误 :cannot convert from int to byte 
//b = b + i; 


9.++i和i++区别,这个一般人都知道,不说了

10.Integer.MAX_VALUE+1=Integer.MIN_VALUE。因为int是有符号数,最大值为0x7FFFFFFF,+1变为0x80000000,这个是负数最小值。这样看int好像是一个循环,超过最大值便成了最小值了。

11。移位.x<<y。如果x是byte,char ,short会被拓展为int再移位,怎么拓展参照前面介绍的拓展方法,如果y超过32会取对32的模,也就是说最多只能移32位,如果x是long型,则y会对64取模。举例
Java代码 
System.out.println(-1 << 31);// -2147483648 向左移31%32=31位 
System.out.println(-1 << 32);// -1 向左移32%32=0位 
System.out.println(-1 << 33);// -2 向左移33%32=1位 
System.out.println(-1 << 1);// -2 向左移1%32=1位 
 
System.out.println(-1L << 63);// -9223372036854775808 向左移63%64=63位 
System.out.println(-1L << 64);// -1 向左移64%64=0位 
System.out.println(-1L << 65);// -2 向左移65%64=1位 



12。double和float有正无穷大和负无穷大的定义,所以double d = 1.0/0.0;这是可以编译和运行的(int和long不行),结果d为Double.POSITIVE_INFINITY。而Double.POSITIVE_INFINITY + 1 == Double.POSITIVE_INFINITY。还有一个Double.NEGATIVE_INFINITY表示负无穷大。

13.double和float有个NaN,它不等于任何数字,包括自己,double d = 0.0/0.0,d即Double.NaN

14.自动拆箱,这个最常见了,目前1.6版本支持。
Java代码 
// 為了兼容以前版本,1.5不會自動拆箱 
System.out.println(new Integer(0) == new Integer(0));// false 
// 1.4编译非法,1.5会自动拆箱 
System.out.println(new Integer(0) == 0);// true 


15.为什么-0x00000000==0x00000000、-0x80000000== 0x80000000.只需要知道,最高位为符号位,0表示整数,1表示负数。内存中是补码表示所有数字的,正数的补码就是其二进制码,而负数的补码需要计算,计算方法:将其绝对值按位取反。然后+1即可。举例。-0x80000000的绝对值为0x80000000,按位取反为0x7FFFFFFF,然后加1等于0x80000000,所以-0x80000000== 0x80000000。

16.Math.abs可能会负数,System.out.println(Math.abs
(Integer.MIN_VALUE));// -2147483648。原因可以abs计算方法:return (a<0)?-a:a,可参照15,知道Integer.Min_VALUE == -Integer.MIN_VALUE.同理Long也类似.

17。不要使用基于减法的比较器。为何?可能会溢出啊,比如
int x = -2000000000;
int y = 2000000000;
显然x是小于y的,如果按照x-y>0来判断,x-y最后是正的,结果就错了。
可使用比较型,如
基于整型的比较器的实现一般使用如下的方式来比较:
Java代码 
public int compare(Integer i1, Integer i2) { 
    return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1)); 



18. int i=-2147483648与int i=-(2147483648)?
前面的式子可以编译通过,后面的编译不通过,为啥,因为int型字面常量,最大值为2147483647.所以int i=-(2147483647)就可以了。


小结:前面这个18个问题都是数值表达式方面的,在平时使用的时候,只要注意别溢出即可。
分享到:
评论

相关推荐

    java 解惑 java 解惑 java 解惑

    java 解惑 java 解惑 java 解惑 java 解惑 java 解惑 java 解惑

    Java解惑(中文版)_java_java解惑_solve65p_

    《Java解惑(中文版)》是一本专为Java初学者设计的学习资料,旨在帮助读者解答在学习Java过程中遇到的各种困惑。"solve65p"可能代表这本书包含65个问题或主题,每个都深入浅出地进行了讲解,旨在解决初学者在编程...

    Java PUZZLE Java 解惑

    Java PUZZLE Java 解惑 Java PUZZLE Java 解惑 Java PUZZLE Java 解惑Java PUZZLE Java 解惑 Java PUZZLE Java 解惑 Java PUZZLE Java 解惑

    Java解惑 中文版

    1. **内存管理**:Java的垃圾回收机制是其一大特色,但也常常引发疑问。书中详细解释了如何理解和控制对象生命周期,避免内存泄漏和性能问题。 2. **异常处理**:异常处理是Java程序的重要组成部分。书中会讲解如何...

    JAVA 解惑 java经典

    1. **Java基础**:这可能包括变量、数据类型、运算符、控制结构(如if语句、for循环、while循环)、方法、类和对象等基本概念。理解这些是Java编程的基础,对于初学者来说至关重要。 2. **面向对象编程**:Java是一...

    Java解惑 布洛克 著;陈昊鹏 译

    《Java解惑》 布洛克 著;陈昊鹏 译 扫描清晰带目录,仅供参阅,请支持正版

    Java解惑.pdf

    1. **基础语法**:Java的基础语法包括变量、数据类型、运算符、流程控制(如if-else,switch,for,while等)、方法定义与调用等。理解这些基础知识是编写任何Java程序的前提。 2. **类与对象**:面向对象编程是...

    "java解惑" PDF版本

    "java解惑" PDF版本

    java解惑 PDF版

    文档《java解惑 PDF版》中列举了95个这样的谜题,每个谜题都旨在帮助开发者理解并纠正一些常见的错误理解。以下是根据提供的部分内容解析的几个相关知识点。 ### 表达式谜题与取余操作符(%)的行为 在Java中,...

    JAVA解惑.pdf

    1. **异常处理**:Java中的异常处理是通过try-catch-finally语句块实现的,异常是一种在程序运行时发生的错误。理解如何妥善地捕获和处理异常是编写健壮代码的关键,避免程序因为未处理的异常而突然终止。 2. **...

    4,JAVA解惑 高清PDF 下载

    《JAVA解惑》是Java开发者领域的一本经典著作,它被广大编程爱好者称为Java四大名著之一,旨在解决初学者及有一定经验的开发者在学习和使用Java过程中遇到的各种困惑。这本书深入浅出地讲解了Java语言的核心概念和...

    java 解惑

    6. **Java 十大基础笔记整理(PDF).zip**:这是一份整理好的Java基础知识点的笔记,涵盖了类、对象、接口、继承、异常处理、输入输出、集合框架等关键概念,适合初学者和复习者参考。 通过这些文件,我们可以系统...

    java解惑 for all javaer

    讲述如何在程序中避免程序缺陷和程序陷阱的,解惑的过程中,介绍了一些Java编程语言中许多不易被掌握的知识点,其阅读价值非常高,适合具有Java知识的学习者和有编程经验的Java程序员阅读。

    java解惑java解惑java解惑

    1. **Java基础** - **变量与数据类型**:Java支持基本数据类型(如int、double等)和引用类型(如类、接口和数组)。理解它们的区别对于正确使用变量至关重要。 - **控制流**:包括if条件语句、for、while循环以及...

    java解惑(包括pdf和答案)

    1. **Java基础知识**:涵盖变量、数据类型、运算符、控制流程(如if语句、for循环、while循环)、函数和方法的定义与调用等。 2. **面向对象编程**:包括类、对象、封装、继承、多态等概念,以及如何设计和实现类。...

    Java解惑(中文).pdf

    "Java解惑(中文).pdf"这份文档很显然是为了帮助Java开发者解决他们在编程过程中遇到的一些常见困惑和误解。这份高清版、文字版的资料很可能包含了深入浅出的解释和实例分析,以中文的形式呈现,使得国内开发者更容易...

    Java解惑(中文).pdf

    1. **内存管理与垃圾回收**:Java的自动内存管理是一个强大的特性,但理解如何工作以及何时进行垃圾回收是至关重要的。书中会详细讲解对象生命周期、引用类型以及如何避免内存泄漏。 2. **多线程**:Java提供了丰富...

    JAVA解惑(JAVA谜题) 中文版(PDF)

    ### JAVA解惑中的关键知识点解析 #### 谜题1:奇数性的判断 在《JAVA解惑》一书中,作者通过一系列实例介绍了Java编程语言中的一些不易掌握的知识点。其中一个例子是关于如何正确判断一个整数是否为奇数。 **原始...

Global site tag (gtag.js) - Google Analytics