java第二篇Java基础

Java分为三个版本:Java SE(标准版)、Java EE(企业版)、Java ME(微型版)。其中JavaSE就是大家学JavaEE和JavaME的基础,换而言之学Java先从JavaSE开始,JavaSE 包含了支持 Java Web 服务开发的类,JavaEE是企业最常用的用于企业级开发应用的,Java ME主要是移动段的开发应用。

eclipse安装教程 : https://blog.csdn.net/Snail__fly/article/details/77278061  

汉化:https://blog.csdn.net/qq_38113556/article/details/79297606

javac 命令是生成后缀为class的字节码文件,它需要写文件的名称和后缀。java命令是为了调用这个文件,它不用写生成的class的文件的后缀,只写名字即可。

JVM:保证java语言跨平台,JRE:Java程勋运行环境,JDK:Java程序的开发环境. JDK: JRE + 工具 。JRE: JVM + 类库。

每个Java应用程序有一个Runtime类的实例,使运行程序与运行环境相连接,Runtime的exec(string)方法可以执行dos命令。通过Runtime的getRuntime返回实例。

Path环境变量的作用是为了让。Exe文件的命令 在任意目录下可用,javac和java命令如果不配path只能在JDK 的bin目录下用,因为Bin里有Java的内部类库和两个的。Exe文件。对可执行文件先在当前路径去找,如果没找到就去path环境变量的配置的路径去找。

导出与导入:如果要用别的项目的类, 把对方类export出成jar包(多个类的集合),然后复制到自己项目路径下然后添加至构建路径,jar包右键buildpath/addtobuildpath。export导出javadoc文档,index文件用浏览器打开

可以用JAVA_HOME 配置path来代替直接在path里添加,这样可以避免因为修改出错,JAVA_HOME 里的path只需要配置到JDK安装目录即可,path里用%JAVA_HOME%/bin;代替原来的path即可。

为什么要配置JDK环境变量?

因为电脑不知道javac和java这个命令是在C:\Program Files\Java\jdk1.8.0_65\bin\(我们的安装路径)的这个路径下面,所以我们要设置好环境变量,来让电脑知道其路径。

CLASSPATH环境变量。作用是指定类搜索路径,要使用已经编写好的类,前提当然是能够找到它们了,JVM就是通过CLASSPTH来寻找类的。我们 需要把jdk安装目录下的bin目录 C:\Program Files\Java\jdk1.8.0_65\bin\(我们的安装路径)设置到CLASSPATH中,当然,当前目录“.”也必须加入到该变量中。其他也有建议把lib子目录中的dt.jar和tools.jar设置其中。

rt.jar是JAVA基础类库,dt.jar是关于运行环境的类库,tools.jar是工具类库,编译和运行需要的都是toos.jar里面的类分别是sun.tools.java.*; sun.tols.javac.*;

elipse中的Java构建路径用于在编译Java项目时找到依赖的类、

1.Java程序的基本结构:大体分为main()主方法,标识符、关键字、语句、注释等。这些跟C#都差不多。。类的首字母大写并且各个单词的首字母大写,常量:在程序执行过程中其值不能改变,分为字面值常量和自定义常量,二进制开头用0b开头,B后缀也表示二进制,八进制以0开头,十六进制以0x开头,如果表示的值是long要在后面加l或L。二进制从右开始,每三位(不足用0补齐)的十进制值,组成的数是八进制,16进制是4位数,

1.1包的定义及注意事项:package 这个关键字,这个关键字用来定义包,来表示你写的类在这个包里。关键字字母都是小写,标识符不能以数字开头,不能用关键字。包其实就是文件夹,对类进行分功能管理,用于把相同的类名进行区分,包的命名全为小写,单级表示一个文件夹,多级表示嵌套的文件夹,嵌套用符号“.”表示.package语句必须是程序的第一条可执行语句,一个java文件只能有一个package语句,如果没有package,默认表示无包。手动运行时, 把class放包的对应目录下,并回到包的根目录带包名运行。class文件。或者编译的时候带上-d 格式: javac -d . HelloWord.java 即可,一样带包名运行。不同包下调用类在不导包的情况下要用包名前缀,导入包用关键字import 包名 。 可以用*导入包下所有,最好是用谁导入谁。package(只能有一个) > import(可以有多个) >class(可以有多个) 顺序。

2.标识符的命名规则:字母、数字、下划线和美元($)符号组成、第一个字符不能为数字。java使用的是Unicode标准字符集,标识符不能使java的关键字和保留字,并且区分大小写。Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

原码,反码。补码:原码:最高位为符号位,0表示整数,1表示负数,其余表示数值大小。正数的反码与原码相同,负数的反码与原码相比是符号不变数值为取反,正数的补码与原码相同,负数的补码是在反码的基础上加1.计算机中数据的运算都是补码进行的。补码转为原码2种方法:

1:如果补码是正数的话,即符号位(一般是最高位) 为0的话,该补码即原码。
2:如果补码是负数的话,即符号位是1的话,在有两种方式将其变为原码。a:在对该补码求补,所得的补码即为原补码的原码 b:符号位在求反码和补码的过程中不变,将补码-1,再将各位取反,得到的反码即为原码

int的取值范围是-2^31 - 2^31-1 ,那最小值是2^31的原因是:1111 1111 | 1111 1111 | 1111 1111 | 1111 1111 这个是最大负整数的原码了,1000 0000 | 0000 0000 | 0000 0000 | 0000 0001 这个是最大负整数对应的补码,那么还有一种情况没有包含进去,就是当补码是全0的情况,也就是-0这种情况,在二进制中0可以表示为-0和+0这两种情况,但是0只有一个,所以取-0这种情况,
当这个最小负整数的补码除符号位外全是0的时候,就是-0的原码了,所以-0是最小的那个数,也就是-2147483648,但其实这个数在内存中并不存在原码,这个补码也不是真正的补码,那么我们再来考虑下如果取的int的值超过这个范围会怎么样,就是正整数超出2147483647范围后出现了循环取值的现象,也就是2147483648溢出后回到了最小负整数-2147483648,2147483649溢出后变成了-2147483648+1=-2147483647,依次类推。

https://blog.csdn.net/The_struggle_of_a_RD/article/details/82631094

        System.out.println(-1 << 31);//-2147483648
        //1111 1111 1111 1111 1111 1111 1111 1110
        //1111 1111 1111 1111 1111 1111 1111 1111
        //1000 0000 0000 0000 0000 0000 0000 0000
        //1111 1111 1111 1111 1111 1111 1111 1111
        //1000 0000 0000 0000 0000 0000 0000 0000 -0的源码
        System.out.println(-1 << 32);//-1
        System.out.println(1 << 32);//1
        System.out.println(1 << 31);//-2147483648

        System.out.println(-1 << 1);//-2
        //1111 1111 1111 1111 1111 1111 1111 1110
        //1111 1111 1111 1111 1111 1111 1111 1111
        //1111 1111 1111 1111 1111 1111 1111 1110
        //1111 1111 1111 1111 1111 1111 1111 1101
        //1000 0000 0000 0000 0000 0000 0000 0010
        //或
        //1000 0000 0000 0000 0000 0000 0000 0001
        //1000 0000 0000 0000 0000 0000 0000 0010
        System.out.println(1 << -1);//-2147483648
        System.out.println(1L << -1);//-2147483648
        //000000000000000000000000000000000000000000000000000000000000001
        //100000000000000000000000000000000000000000000000000000000000000
        System.out.println(1L << -2);//4611686018427387904
        //向左移-1位就是向右移1位 第一位是符号位,所以是负数,如果多移一位的话就是正数了
        System.out.println(1 >>> -32);//1
        System.out.println(1 >> -32);//1
        System.out.println(1 >>> -20);//0
        System.out.println(1 >> -20);//-1

如果左侧操作数的类型为int,则仅将右侧操作数的最低5位用作移位距离。 就像右侧操作数受到掩码值0x1f(0b11111)的按位逻辑AND运算符&一样。 因此,实际使用的移动距离始终在0到31(含)范围内。 就是说,1<<-1 等价于1<<31。

3.有8种基本类型,6种为数值类型,另外两种为字符和布尔类型。6种数值类型又分为4种整数和2种浮点数。

byte 1个字节(8位)、 short 2 个字节16 位 、int 4个字节 32位(9-10位有效数字)、long 8 个字节 64位(18-19有效数字)。float:4个字节,32位,double : 8个字节,64位。对long型变量赋值时结尾必须加上l或者L,如果不加系统默认为int,float型赋值结尾加F或者f。如果不加f系统自动将其定义为double。为double赋值时,后面可加D或者d,也可以不加。整数类型在java中有三种表示形式,十进制,八进制:逢八进一,最大数字为7且必须以0开头,十六进制:逢16进1,每位最大数字15,以0X或0x开头 0~9 a~f (大小写均可),二进制用0b开头。字符类型:char存储单个字符 2个字节,用单引号,char x = ‘a’ 或者 char x = 97;  后者是因为a在unicode表中位置在97位。布尔类型:true和false ,boolean类型到底占用几个字节的内存,具体还要看虚拟机实现是否按照规范来,所以1个字节、4个字节都是有可能的,通常的jvm来说boolean类型单独使用是占了4个字节,在数组中一个boolean元素又是占了1个字节,使用int的原因是,对于当下32位的处理器(CPU)来说,一次处理数据是32位(这里不是指的是32/64位系统,而是指CPU硬件层面),具有高效存取的特点。两种浮点数类型(float、double):    float:32 位,后缀 F 或 f,1 位符号位,8 位指数,23 位有效尾数。    double:64 位,最常用,后缀 D 或 d,1 位符号位,11 位指数,52 位有效尾数 。lua里的number类型为双精度浮点数。float能代表的十进制 的小数点后最大精度为7位,double 能代表的 十进制 的小数点后最大精度是15位。decimal(c#):16字,1个符号位,31位指数,96位尾数,共128位,能拥有更高的精度:28位,后缀为m ,28~29位有效数字。decimal的有效位数很大,达到了28位,但是表示的数据范围却比float和double类型小。decimal的二进制表示形式由1位符号、96位整数和比例因子组成,用于划分整数号,并指定它的哪一部分是小数部分。 缩放系数隐式为数字10,指数范围为0到28。0到15是未使用的,并且必须为零。位16到23必须包含一个介于0到28之间的指数,该指数指示10的幂来除以整数。不使用 24 到30位,并且必须为零。31位包含符号;0表示正,1表示负。

        float f1=12.1234561f;//f1=12.123456
        float f2=12.1234565f;//最后一位为了检验四舍五入用f2=12.123457
        float f3=12.1234570f;//最后一位写成0,不会显示出来f3=12.123457
        float f4=123.1234570f;//f4=123.12346
        float f5=1234.88995f;//f5=1234.8899
        float f6=12345.8899f;//f6=12345.89
        float f7=123456.8899f;//f7=123456.89
        float f8=1234567.88990f;//f8=1234567.9

        double d1=123456.12345678902;//17位
        double d2=123456.12345678906;//最后一位为了检验四舍五入用
        double d3=123456.12345678909;//最后一位为了检验四舍五入用 
        double d4=123456.12345678910;//最后一位写成0,不会显示出来
        double d5=123456.123456789086;//18位
        double d6=123456.123456789087;//18位 

        System.out.println("zhuan="+(float)d1);//zhuan=123456.125
        System.out.println("d1="+d1);//123456.12345678902
        System.out.println("d2="+d2);//123456.12345678906
        System.out.println("d3="+d3);//123456.1234567891
        System.out.println("d4="+d4);//123456.1234567891
        System.out.println("d5="+d5);//123456.12345678908 //省去了6  共17位 
        System.out.println("d6="+d6);//123456.1234567891 //16位


        System.out.println(0.05+0.01);//0.060000000000000005
        System.out.println(1.0-0.42);//0.5800000000000001
        System.out.println(4.015*100);//401.49999999999994
        System.out.println(123.3/100);//1.2329999999999999

        BigDecimal aa = new BigDecimal(0.31);
        BigDecimal bb = new BigDecimal(0.2);
        BigDecimal cc = new BigDecimal(0.11);


        System.out.println(aa.subtract(bb).doubleValue()); //转换成double 0.10999999999999999
        System.out.println(aa.subtract(bb));//0.109999999999999986677323704498121514916419982910156250
        System.out.println(cc.compareTo(aa.subtract(bb)));//1
        //BigDecimal其中一个构造函数以双精度浮点数作为输入,然而得到的结果仍然不是我们想要的。
        //要小心使用 BigDecimal(double)构造函数,因为如果不了解它,会在计算过程中产生舍入误差。请使用基于整数或 String 的构造函数。
        //在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,
        //在商业计算中我们要用java.math.BigDecimal。使用BigDecimal并且一定要用String来够造。

        BigDecimal aa2 = new BigDecimal("0.31");
        BigDecimal bb2 = new BigDecimal("0.2");
        BigDecimal cc2 = new BigDecimal("0.11");

        System.out.println(aa2.subtract(bb2).doubleValue());//0.11
        System.out.println(aa2.subtract(bb2));//0.11
        System.out.println(cc2.compareTo(aa2.subtract(bb2)));//0
//        如浮点类型一样,BigDecimal 也有一些令人奇怪的行为。尤其在使用 equals() 方法来检测数值之间是否相等时要小心。
//        equals() 方法认为,两个表示同一个数但换算值不同(例如, 100.00 和 100.000 )的 BigDecimal 值是不相等的。然而,
//        compareTo() 方法会认为这两个数是相等的,所以在从数值上比较两个 BigDecimal 值时,应该使用 compareTo() 而不是 equals() 。
//        另外还有一些情形,任意精度的小数运算仍不能表示精确结果。例如,1 除以 9 会产生无限循环的小数 .111111... 。
//        出于这个原因,在进行除法运算时,BigDecimal 可以让您显式地控制舍入java.math.MathContext和java.math.RoundingMode。
//        movePointLeft() 方法支持 10 的幂次方的精确除法。
        BigDecimal aa3 = new BigDecimal("0.31");
        BigDecimal bb3 = new BigDecimal("0.310");
        BigDecimal cc3 = new BigDecimal("0.123456789");
        System.out.println(aa3.compareTo(bb3));//0
        System.out.println(aa3.equals(bb3));//false
        System.out.println(aa3.movePointLeft(3));//0.00031

浮点数的有效位数:float输出,前7位有效数字是真实值,第8位是估算值,可能和原始一致,可能是四舍五入上来的。这个结果和数学一致。因此可以得出,java下float有8位有效数字的结论。

double值,前15位有效数字是真实值,第16位是估算值,可能和原始一致,可能是四舍五入上来的(得出结论,java下double有16位有效数字的结论。

double转float为什么是9位输出?矛盾吗?从代码可以看出,前8位有效数字是没问题的,第9位的输出和原数字没啥关系,也不符合四舍五入,因此不必过于担心,8位有效数字依然成立,至于显示出第9位的值,不能保证其准确性。

至于此处显示的第17位,仅仅是因为其在理论范围内的值。为了进一步测试,换了几个数值。如图(没错!d5正常显示17位,d6就进位了16位。原因:二进制位可以解释。因此,有效数字应该是以二进制为准,从数学上看,float的可以显示8-9位,double可以显示16-17位。

浮点数的取值范围:

        System.out.println(Double.MAX_VALUE);//1.7976931348623157E308
        System.out.println(Double.MIN_VALUE);//4.9E-324
        System.out.println(Double.MIN_VALUE > 0); //true
        System.out.println(Float.MAX_VALUE);//3.4028235E38
        System.out.println(Float.MIN_VALUE);//1.4E-45
        float s = 0;//0.0
        System.out.println(s == 0);//true

浮点数:对于一个整数,我们可以很方便的在十进制与二进制中转换,但是对于一个浮点数来说不是这么容易——因为小数点的存在。对于浮点数来说,小数点的位置不是固定的(小数点后面的数的个数不定),所以如何存储小数点是一个挑战。后来人们想出用科学计数法通常如这般:3.12*10^5来表示浮点数,这样的好处是:小数点的位置固定下来了。因为计算机只能用二进制表示数据,所以我们用2来表示上面提到的那个10.

对于float型数据,其长度是4个字节,右边23位用来表示小数点后面的数字,中间8位用来表示e,左边一位用来表示正负。

对于double型数据,其长度是8个字节,右边52位用来表示小数点后面的数字.中间11位表示e,左边一位用来表示正负。

指数偏移量=2^k-1,k为指数位个数。

因为e可以为正,可以为负数。比如1.10110*2^4 这个e为正数,如果是0.101那么用指数表示就是1.01*2^-1,那么e为-1。同时要求先把e+指数偏移量,得到的结果再化成二进制,就是我们的指数位。

小数部分:把小数点后面的数字。如上面的10110,位数不够就补零。

符号位:1表示负数,0表示正数。

特殊情况:

当指数位(阶码)为全0且小数部分(尾数)也为全0时,表示的真值为零。

当阶码为全1且尾数也为全0时,表示的真值X为无穷大(∞),结合符号位S为0或1,有+∞和-∞之分。如果尾数不全位0,表示这不是一个数(NaN)

除去E用全0和全1(255)表示零和无穷大的特殊情况,因此,阶码的取值范围变为1~254,为了表示小数,设置偏移量为127,那么阶码实际表达的数值的指数范围为-126 ~ +127.

27.5的二进制为11011.1

1.10111*2^4

尾数(小数点后的数)10111,补够23位 1011 1000 0000 0000 0000 000

指数:4,加上127,就是131,二进制1000 0011

用二进制表示就是 (符号数位1位)0 (指数位8位)1000 0011 (尾数位23位)1011 1000 0000 0000 0000 000

写成二进制标准形式:0100 0001 1101 1100 0000 0000 0000 0000

在计算机内部保存尾数时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。2的23次方是8388608,即6-7位有效位数(整数位+小数位),同理,double 的有效位数是2的52次方,有效位数为15-16.

十进制小数转二进制小数:乘二取整,顺序排列,有无限循环的精度损失,例如十进制0.4,转换为二进制位0.0110 0110 0110 0110 ......

  0.4 * 2 = 0.8 ------ 0

  0.8 * 2 = 1.6 ------ 1

  0.6 * 2 = 1.2 ------ 1

  0.2 * 2 = 0.4 ------ 0

  ......

二进制小数转十进制:从小数点后开始,依次乘以2的负一次方,2的负二次方,2的负三次方等。例如二进制数0.001转换为十进制。例如:0.001

0 * 1/2  + 0 * 1/4 + 1* 1/8 = 0.125

4.变量和常量:在程序执行过程中,值不能改变的量称为常量,能改变的称为变量。声明变量时编译器给这个变量分配了空间。常量:用关键字final限定,语法:final 数据类型 常量名 =  值  ,成员变量的常量必须在定义时就赋值。方法体内的局部变量不用。成员变量又分为静态变量(类型。静态变量) 和实例变量(对象。实例变量)。方法结束。方法中的局部变量占用的内存会被释放。局部变量也随之销毁。

5.运算符: 一元运算符(!从右到左, 与和或从左到右),二元运算符,三元运算符。逻辑运算符   &&和|| 针对boolean类型,可以只判断一次 。而&和| 必须判断两个表达式。位运算符:~反、&与、|或、^异或、<< 左移、>>右移(正数右移高位补0,负数右移高位补1) 、无符号右移>>>(无符号无论是正数还是负数,高位通通补0)。异或:同时为0或者同时为1 时 结果为0 否则为1,相同为false,不同为true.结果的精度与精度高的操作数相同。左移就是这个数乘以2的n次方,左移就是左边最高位丢弃,右边补齐0.,右移就是除以将这个数除以2的n次方(y/2),最高位是0,左边补齐0,最高位是1,左边补齐1, 无符号右移 无论最高位是0还是1 左边补齐0, 所有操作都是操作补码,得到的也是补码。三元运算符 boolean b = 20<50?true : false.运算符优先级:如果两个运算有相同的优先级,那么左边的表达式要比右边的表达式先被处理。尽量用()来限定优先顺序。如果想得到除后的小数,只需要把操作数据中的任意一个数据变为浮点数。字面值常量如10,不能使用10++ 或++10,只能用变量++或++变量,扩展的赋值运算符隐含了一个强制类型转换。所以 short s = 1; s += 1 不报错, 而 s = s + 1 是错的。shoet s += 1 也是错的, 初始化用 “=”。位运算符:~反 ,取反首先的得到的是补码,需要转换为反码在转换为原码,这里整数的原码和反码,补码相同,所以可以直接取反,但是如果是负数取反, 首先把负数的原码变为补码在运算,因为计算机的操作都是通过补码来操作的,某一个数据被另一个数据位异或两次,该数本身不变。异或常用来两个两个值的交换,而不必使用临时变量。例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:a = a^b;b = b^a;a = a^b;

<< 左移,相当于乘以2的n次方,例如:1<<6 相当于1×64=64,3<<4 相当于3×16=48

>> 右移,相当于除以2的n次方,例如:64>>3 相当于64÷8=8

三元运算符://运算符内部 从左往右,true和false情况只执行一个,两个三目运算符之间  从左到右

        char a = 'A';
        int i = 0;
        System.out.println((true ? a : 0) + "," + (false ? i : a));//A,65
        //65是因为 他们两个要转换成相同的类型,且是转换成true所在位置变量的类型
        float i2 = 0;
        int b =10;
        System.out.println(false ? i2 : b);//10.0

        int i = 10, j = 10;
        int r = true ? i++ : true ? ++j : --j;
        System.out.println("r= " + r + " i= " + i + " j= " + j);// r=10 i=11 j=10

        boolean result = false ? false : true == false ? true : false;
        System.out.println(result); //false

二进制的四则运算:

加法:0 + 0 = 0 , 0 + 1 = 1 , 1 + 0 = 1, 1 + 1 = 10

减法:二进制的减法和十进制类似,先把数位对齐,同一数位不够减时,从高位借位,借一当二。

乘法:0 x 0 = 0 ,0 x 1 = 0 ,1 x 0 = 0 ,1 x 1 = 1  跟十进制的乘法一样

除法:跟十进制的除法一样,每一位不是0就是1

6.类型转换:隐式类型转换和显示类型转换。 自动类型转是在运算符操作后得到的结果会自动称为高级别的类型。把高精度的变量赋值给低精度的变量需要强制转换,且不可超出变量的取值范围, 否则会发生数据溢出。用()进行强转。不能类型运算时先把小的类型转化成大的类型再参与运算,byte,short,char参与运算首先转换成int类型,并且 byte,short,char 之间不相互转换。

7.一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译器会把内置类型装箱为包装类。相似的,编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包。Character 类用于对单个字符进行操作,Character 类在对象中包装一个基本类型 char 的值。Character类提供了一系列方法来操纵字符。你可以使用Character的构造方法创建一个Character类对象,将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。 这种特征称为装箱,反过来称为拆箱。在金融计算中,必须要使用BigDecimal,double和float都不适合。“BigDecimal可以表示任意精度的小数,并对它们进行计算。但要小心使用 BigDecimal(double) 构造函数,因为它会在计算的过程中产生舍入误差。最好要使用基于整数或 String 的构造函数来创建BigDecimal对象。” 

2 / 0的时候程序会报java.lang.ArithmeticException的错误,那么你知道2.0 / 0的结果是Infinity,其实就是无穷的意思。不仅有正无穷大,还有负无穷大,甚至还有一个叫做NaN的特殊值。NaN代表‘不是一个数字’。这些值的存在是为了在出现错误条件时,程序还可以用特定的值来表示所产生的结果。这些错误的情况包括算术溢出、给负数开平方根,还有您说的除以 0 等。

BigInteger:可以让超过Integer范围的数据进行运算,它支持任意精度的整数,是不可变的,在进行每一步运算时,都会产生一个新的对象,发生异常算术条件时,会抛出ArithmeticException异常。BigDecimal:由于float和double数据在运算的时候容易丢失数据,所以为了能精确表示,计算浮点数,java提供了BigDecimal,支持任何精度的定点数,可以用它来精确计算货币值,是不可变的。只有一个构造方法准确:用字符串参数new BigDecimal对象是准确的,其他存在风险,比如double 参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值,值会变大,两者都需要调用对应的算数方法。

因为在学java之前有别的语言基础,所以这里就不做过多详细解释,只是当做复习。过会还会发一篇循环队列的帖子 有需要的小伙伴可以拿走。

JDK7新特性:1.二进制字面量 :int x = 0b100101 ;x为37 2. 数字字面量可以出现下划线: int y = 1_1123_1000;但不能出现在进制标识和数值之间。不能出现在小数点旁边。不能出现在数值开头和结尾、。泛型简化:new 的<>里可以省略类型。try..catch语句的try后可以加一个(),()里放java.lang.AutoClosedable的子类对象, 对象可以自动释放,自动关闭。可以关闭一些流类的对象。public <T> List<T> fuck(T ...) 第一个T是用来声明类型参数的,后面两个是泛型的实现。

Integer  通过 valueOf 获得的对象在-128-127 之间 比较的时候返回true  因为 在这个区间内的Integer 会把对象存在一个数组里,创建Integer的时候有对应的值直接返回对应对象, 跟字符串池差不多。但是Float不行,它返回的是false.   但是Integer new出来的对象是不等的。

Integer a = new Integer(1);
Integer b = new Integer(1);

Integer c = 1000;
Integer d = 1000;

Integer e = Integer.valueOf(1000);
Integer f = Integer.valueOf(1000);

System.out.println(a==b);//false
System.out.println(c==d);//false
System.out.println(e==f);//false


Integer a = new Integer(127);
Integer b = new Integer(127);

Integer c = 127; //相当于Integer.valueOf(127);
Integer d = 127;

Integer e = Integer.valueOf(127);
Integer f = Integer.valueOf(127);

System.out.println(a==b);//false
System.out.println(c==d);//true
System.out.println(e==f);//true

    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

(Object)1操作:其实做了Object ii = Integer.valueOf(1);操作,底层还是integer引用。

Object sObject = (Object)1;//java.lang.Integer 
System.out.println(sObject.getClass().getTypeName());

decode 和 valueof 方法都返回Integer

想要获得Integer:

String 为十进制. 采用valueof(String)合适. 非十进制,采用decode(String)  字符串最前 # ,0x, 0X 代表16进制 ,010代表 8进制

想要获得int

String 为十进制. 采用parseInt(String )合适. 非十进制,采用parseInt(String ,int)

对于Java中的运算操作,例如自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的。num++解析为num=num+1,明显,这个操作不具备原子性,多线程并发共享这个变量时必然会出现问题.

顺带说下volatile关键字很重要的两个特性:

1、保证变量在线程间可见,对volatile变量所有的写操作都能立即反应到其他线程中,换句话说,volatile变量在各个线程中是一致的(得益于java内存模型—"先行发生原则");

2、禁止指令的重排序优化;

那么换成volatile修饰count变量后,会有什么效果呢? 结果似乎又失望了,测试结果是错误的。这又是为什么么? 上面的论据是正确的,也就是上面标红的内容,但是这个论据并不能得出"基于volatile变量的运算在并发下是安全的"这个结论,因为核心点在于java里的运算(比如自增)并不是原子性的。

AtomicInteger 的方法incrementAndGet()方法是原子性的。incrementAndGet()方法在一个无限循环体内,不断尝试将一个比当前值大1的新值赋给自己,如果失败则说明在执行"获取-设置"操作的时已经被其它线程修改过了,于是便再次进入循环下一次操作,直到成功为止。这个便是AtomicInteger原子性的"诀窍"了。

Random类:构造方法分为给种子和不给种子。给同一个种子每次从头开始的随机数是一样的,不给种子是不一样的,里面的nextInt方法给参数的话就是【0)随机,不给的话默认int范围内。运行中重新setSeed就会从重新开始随机。

Random: nextFloat方法返回[0,1), nextBoolean,返回true或者false,nextInt(n)返回【0,n)

Math.random方法是返回一个【0, 1),如果随机1-100  结果乘以100 + 1 再强转(int)即可。 这里强转的时候不会四舍五入,直接取floor。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值