1、包装类、自动装箱、拆箱、享元模
1、包装类概念:java为8个基本数据类型设计了一个包装类,为其提供字段和方法,方便使用。
2、包装类继承体系
数值类型的包装类继承了抽象父类Number,而Number类继承Object类,其他的(Boolean Character)直接继承Object,包装类均位于java.lang包下。
3、包装类的创建对象
类名 对象名 = new类名( 对应类型的变量); 具体的()里面放什么参数 查api的对应类型的构造方法。
Integer aa = new Integer(100);
4、自动装箱和拆箱
装箱:基本数据类型转换为包装类型
拆箱:包装类型转换为 基本数据类型
装箱过程(1.直接赋值 Integer i = 10; (自动装箱) 2.构造方法传值 Integer aa = new Integer(100); 3. valueOf(基本类型变量) Integer in = Integer.valueOf(a); )
拆箱过程(1.直接赋值 int c = new Integer(100); (自动拆箱) 2. 基本数据类型 变量名 = 包装类对象名.xxxValue() int value = in.intValue(); )
5、享元模
简单的理解为:对象之间可以共享,当超出某个范围外就会重新创建对象
java中的String类就是采用该模式创建的一个类
参考:https://blog.csdn.net/justloveyou_/article/details/55045638
public class Hello { public static void main(String[] args) { // Integer integer = new Integer("你给我转啊"); //编译成功,运行报错,数据格式异常。 Integer aa = new Integer(100); Integer bb = new Integer("100"); System.out.println(aa == bb); //false System.out.println(aa.equals(bb)); //true Integer i = 10; Integer j = 10; System.out.println(i.equals(j)); //true String a = "nihao"; String b = "nihao"; System.out.println(a.equals(b)); //true System.out.println(a==b);//true System.out.println(s.equals(new String("nihao"))); //true Hello o = new Hello(); Hello p = new Hello(); System.out.println(o.equals(p)); //false Integer ge1 = 128; Integer ge2 = 128; System.out.println(ge1.equals(ge2));//true System.out.println(ge1 == ge2); //false /* * 享元模式: * 简单的理解为:对象之间可以共享,当超出某个范围外就会重新创建对象 * java中的String类就是采用该模式创建的一个类 * */ } }
2、 Integer 包装类的常用方法
/* * Integer类的常用方法 */ public class Integer_Lei { public static void main(String[] args) { int a = 32; String year = "2018"; //1. Integer.parseInt(String s); 用于将字符串转换成基本数据类型(int),要求字符串必须是数字格式。 System.out.println(Integer.parseInt(year)); // 2018 //2. Integer.parseInt(String s,int radix); 将字符串s按照radix进行转换相应的进制数,然后运行的结果都是以十进制的形式打印。 //指定y的进制为2进制 System.out.println(Integer.parseInt("111",2)); //7 //指定age的进制为16进制 System.out.println(Integer.parseInt("A5",16)); //165 //3. Integer.toString(int i, int radix) 将int整数转成指定的进制数 System.out.println(Integer.toString(15,7)); //21 //4. 十进制转成不同的进制,三个静态方法的返回值都是以字符串的形式返回 System.out.println(Integer.toBinaryString(11)); //1011 二进制 System.out.println(Integer.toOctalString(11)); //13 八进制 System.out.println(Integer.toHexString(11)); //b 十六进制 //5.基本数据类型(int) 转换成字符串 // 5.1 任何类型+"" 变成String类型(推荐使用) String str = 53+""; System.out.println(str); //"53" 打印出来的没有"" ,知道是字符串就好。 // 5.2 Integer类中的toString()将整数值转换成字符串 System.out.println(Integer.toString(a)); //"32" //6. Integer的两个静态成员变量 MIN_VALUE MAX_VALUE System.out.println("int最大值是:"+Integer.MAX_VALUE); //2 31-1 System.out.println("Long最大值是:"+Long.MAX_VALUE); //2 63——1 } } //7. Integer.decode() 和 Integer.valueof() 的区别 Integer.decode()合适用来分析数字 可以分析 8进:010=>分析后为 8 10进:10=>分析后为 10 16进:#10|0X10|0x10=>分析后是 16 而 Integer.valueof() 只能数字的String .像 "010" 这样的8进制 他会解析成 =>10
3、Character包装类的常用方法
构造方法:
public Character(char value)
构造一个新分配的 Character 对象,用以表示指定的 char 值
Character类的判断功能:
public static boolean isDigit(char ch)确定指定字符是否为数字。
public static boolean isLetter(char ch)确定指定字符是否为字母。
public static boolean Character.isSpaceChar(ch);//判断字符是不是空格
public static boolean isLowerCase(char ch)确定是否是小写字母字符
public static boolean isUpperCase(char ch)确定是否大写字母字符
两个转换功能:
public static int toLowerCase(char ch)使用取自 UnicodeData 文件的大小写映射信息将字符参数转换为小写。
public static int toUpperCase(char ch)使用取自 UnicodeData 文件的大小写映射信息将字符参数转换为大写。
4、System 类常用的方法
System类在 jdk中文文档 表示没有构造方法,故不能创建对象,其实查看源码发现system类的 无参的构造方法被私有化(即被private关键字修饰)。
System类里面有out属性,该属性类型为 printStream ,而这个 printStream.java类 中有 println()方法。
/** * system类的构造方法被私有化(即被private关键字修饰),故不能在外界创建对象。 * System类中的都是静态方法(static关键字修饰),类名访问即可。下面是五个常用的方法。 * @author 甘劭 */ import java.util.Arrays; public class HaHa { public static void main(String[] args) { System.out.println(System.currentTimeMillis());//获取当前系统时间与1970年01月01日00:00点之前的毫秒差值 //System.exit(0);//结束正在运行的Java程序,通常传入0记为正常状态,其它为异常状态。 System.out.println("不能运行了"); //System.gc(); //用来运行JVM中的垃圾回收器,完成内存中垃圾的清除。 //System.out.println(System.getProperties());//确定当前的系统属性 //System.arraycopy(src, srcPos, dest, destPos, length); //从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。没有返回值。 /* Object src : 原数组 int srcPos : 从原数据的起始位置开始 Object dest : 目标数组 int destPos : 目标数组的开始起始位置 int length : 要copy的数组的长度*/ byte[] s1 = new byte[]{0,1,2,3,4,5,6,7,8,9}; // 源数组 byte[] s2 = new byte[7]; // 目标数组 System.arraycopy(s1,1,s2 ,2,5); System.out.println(Arrays.toString(s1)); System.out.println(Arrays.toString(s2)); } } //运行结果 //1543924760287 //不能运行了 //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] //[0, 0, 1, 2, 3, 4, 5]
5、String类的常用方法
import java.util.Arrays; // String类 常用的方法 public class String_Lei { public static void main(String[] args) { //1. String类 常用的 构造方法 // 1.1 public String(); 空参构造 初始化一个新创建的 String 对象,使其表示一个空字符序列 // 注意,由于 String 是不可变的,所以无需使用此构造方法。 // 1.2 方法: public String(char[] value) 用字符数组value创建一个String对象 char[] value ={'a','b','c','d','e'}; String str1 = new String(value); System.out.println(str1); //"abcde" // 1.3 public String(char chars[], int x, int n) 用字符数组以x开始的n个字符创建一个String对象 String str2 = new String(value, 1, 3); //字符串下标从0开始 System.out.println(str2); //"bcd" //2. String类中 常用的 判断方法 // 2.1 boolean equals(Object obj); // 将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。 // 2.2 boolean equalsIgnoreCase(String str); // 将此 String 与另一个 String 比较,如果两个字符串的长度相同,且相应字符都相等(忽略大小写),则认为这两个字符串是相等的。 // 2.3 boolean contains(String str); // 当且仅当此字符串包含指定的 字符串 值序列时,返回 true。 String s1 = "abcdefg"; String s2 = "bcde"; System.out.println(s1.contains(s2)); //true // 2.4 boolean startsWith(String str); boolean endsWith(String str); // 判断是否 以 某个 字符串 开头/结尾 System.out.println(s1.startsWith("ab")); //ture System.out.println(s1.startsWith("bc")); //false // 2.5 boolean isEmpty(); 当且仅当 length() 为 0 时返回 true String s3 = ""; String s4 = null; System.out.println(s3.isEmpty()); //true // System.out.println(s4.isEmpty()); //NullPointerException 空指针异常 //3. String类中的获取方法 // 3.1 int length(); 返回此字符串的长度。 数组中的length是属性,String类中的length()是方法; // 3.2 Char charAt(int index); 返回指定 索引 处的 char 值。索引范围为从 0 到 length()-1。 // 3.3 int indexof(int ch); 返回指定 字符 在此 字符串 中第一次出现处的索引 // 3.4 查找子串在字符串中的位置 //public int indexOf(String str) //返回指定 子字符串 在此 字符串 中第一次出现处的索引。若没有出现则返回-1。 //public int indexOf(String str, int fromIndex) //该方法与第一种类似,区别在于该方法从fromIndex位置向后查找。 //public int lastIndexOf(String str) //该方法与第一种类似,区别在于该方法从字符串的末尾位置向前查找。 //public int lastIndexOf(String str, int fromIndex) //该方法与第二种方法类似,区别于该方法从fromIndex位置向前查找。 // 3.5 substring(int start); 从指定位置开始截取字符串,默认都末尾; // substring(int beginIndex, int endIndex) 从指定位置开始到指定位置截取字符串,前包后不包。 //4. String类的转换功能 // 4.1 byte[] getBytes();使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一 个新的 byte 数组中。 byte[] ch1 = s1.getBytes(); System.out.println(Arrays.toString(ch1)); // [97, 98, 99, 100, 101, 102, 103] // 4.2 char[] toCharArray(); 将此字符串转换为一个新的 字符 数组。 char[] ch = s1.toCharArray(); System.out.println(Arrays.toString(ch)); // [a, b, c, d, e, f, g] // 4.3 String.valueOf(char[] date);把 字符数组 转换成 字符串; char[] v1 ={'a','b','c','d','e'}; String aa = String.valueOf(v1); System.out.println(aa); // "abcde" // 4.4 String.valueOf(int i);把int类型的数据转换成字符串. // 注意:String类的valueOf方法可以把任意类型的数据转成字符串; System.out.println(String.valueOf(412412.434)); //"412412.434" //5. String类的其他方法 // 5.1 String replace(String old,String new); // 返回一个新的字符串,使用指定的字面值 (后面的字符串)替换 此字符串所有 相匹配子字符串(前面的字符串)。 String oldStr = " abc defg "; String newStr = oldStr.replace("f", "HHHH"); System.out.println(newStr); // " abc deHHHHg " // 5.2 trim();去掉字符串两端的空格,中间的空格无法去掉 System.out.println(oldStr.trim()); //"abc defg" // 5.3 concat() 将指定字符串连接到此字符串的结尾。 String ss = "哈哈u4e00-u9fa5"; String ssb ="一个汉字两个字符,汉字的范围"; System.out.println(ss.concat(ssb)); //"哈哈一-龥一个汉字两个字符,汉字的范围" // 5.4 split() 根据给定 正则表达式 的匹配拆分此字符串。 此方法返回的 字符串数组 包含此 字符串的子字符串。 // 其中:“.”和“|” “+” “*” 都是转义字符,必须得加"\"; String[] sa = "aaa|bbb|ccc".split("\|"); System.out.println(Arrays.toString(sa)); // [aaa, bbb, ccc] // 还有如果想在串中使用""字符,则也需要转义.首先要表达"aaaabbb"是错误的,应该用"aaaa\bbbb"才对。 String[] sb = "aaa\bbb\ccc".split("\\"); System.out.println(Arrays.toString(sb)); // [aaa, bbb, ccc] // 5.5 compareTo() 比较字符串的大小 返回的是一个int类型值。 判断字符串大小的依据是:比较 对应的字符 在(ASCII码顺序)。 /* 1、如果字符串相等返回值0 2、如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值(ASCII码值) (负值代表:前字符串的值小于后字符串,正值代表:前字符串大于后字符串) 3、如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较, 以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度. */ String xx = "abc"; String yy = "abczzz"; System.out.println(xx.compareTo(yy)); //-3 // 5.6 compareToIgnoreCase() 方法是不区分大小写,返回值是int,比较方式与compareTo()相同 String ss1 = "adger"; String ss2 = "adgerfa"; String ss3 = "ADGER"; String ss4 = "adher"; System.out.println(ss1.compareTo(ss2));//-2 System.out.println(ss1.compareTo(ss3));//32 System.out.println(ss1.compareToIgnoreCase(ss3));//0 System.out.println(ss3.compareToIgnoreCase(ss4));//-1 } }
6、String,StringBuilder,StringBuffer三者的区别
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
1、首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:
String str="abc"; System.out.println(str); str=str+"de"; System.out.println(str);
如果运行这段代码会发现先输出“abc”,然后又输出“abcde”
首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
另外,有时候我们会这样对字符串进行赋值
String str="abc"+"de"; StringBuilder stringBuilder=new StringBuilder().append("abc").append("de"); System.out.println(str); System.out.println(stringBuilder.toString());
这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和
String str="abcde";是完全一样的,所以会很快,而如果写成下面这种形式
String str1="abc"; String str2="de"; String str=str1+str2;
那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。
2、再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3、总结一下
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
7、创建空字符串的三种情况
String s = new String(); String s = ""; String s = null;
注意: “” 和null的区别:
“”是字符串常量.同时也是一个String类的对象,既然是对象当然可以调用String类中的方法;
Null是空常量,不能调用任何的方法,否则会出现空指针异常,null常量可以给任意的引用数据类型赋值
public class Test { public static void main(String[] args) { //创建空字符串的三种方式 String str1 = null; // 表示str1没有指向一个对象 String str2 = ""; // 有一个对象,对象是空, String str3 = new String(); // 和上面差不多 System.out.println(str1==str2); //false System.out.println(str1==str3); //false System.out.println(str2==str3); //false System.out.println(str2.equals(str1)); //false System.out.println(str2.equals(str3)); //true System.out.println(str3.equals(str1)); //false System.out.println(str3.equals(str2)); //true System.out.println(str1.equals(str2)); //尽量使用一个已知的值去和未知的值比较。尽可能的避免空指针异常。} } }
8、创建字符串的两种方式
1、String str1= “abc”;
在编译期,JVM会去常量池来查找是否存在“abc”,如果不存在,就在常量池中开辟一个空间来存储“abc”;如果存在,就不用新开辟空间。
然后在栈内存中开辟一个名字为str1的空间,来存储“abc”在常量池中的地址值。
2、String str2 = new String("abc") ;
在编译阶段JVM先去常量池中查找是否存在“abc”,如果过不存在,则在常量池中开辟一个空间存储“abc”。在运行时期,通过String类的构造器在堆内存中new了一个空间,
然后将String池中的“abc”复制一份存放到该堆空间中,在栈中开辟名字为str2的空间,存放堆中new出来的这个String对象的地址值。
也就是说,前者在初始化的时候可能创建了一个对象,也可能一个对象也没有创建;后者因为new关键字,至少在内存中创建了一个对象,也有可能是两个对象。
常量池存放在方法区里面,与堆栈是并列关系
jdk1,6常量池放在方法区,jdk1.7常量池放在堆内存,jdk1.8放在元空间里面,和堆相独立。所以导致string的intern方法因为以上变化在不同版本会有不同表现。
Java中的垃圾回收机制(了解)
System.gc(): 通知JVM执行垃圾回收机制。
finalize():当垃圾对象被回收是,自动调用。
垃圾对象:堆空间中的对象不能被栈空间中变量所引用。
9、创建了几个字符串对象的面试题
注意:一般这种问法不会考虑常量池中的对象,是问堆中的对象,如果是当面问,可以给他说说有常量池这么一个东西,表示你知道有这么回事。
①、 String s1 = “A” + “hello” 在编译成class的时候,就是编译器,因为”A”和”helllo”都是确定的常量,直接编译成”Ahello”,这个也是一个确定的常量,直接在常量区,堆中不会有对象。
②、 String s2 = “A”;//常量区
String s3 = s2 + “hello”; //你使用了+,要改变我字符串,我就不会存在在常量区了,我就跑到堆中去了,所以堆中:A hello Ahello 3个对象
③ 、String s4 = new String(“A”) + new String(“hello”);
很明显,直接使用了new关键字,堆中!!!!字符串不能更改,一个new就是一个,在来一个+号,又增加了一个。就是三个: A hello Ahello
10、 Runtime类常用方法
import java.io.IOException; public class Test { // Runtime类,他是一个与JVM运行时环境有关的类,该类不能创建对象,因为构造方法私有化了(单例模式); public static void main(String[] args) throws IOException { //可以取得当前JVM的运行时环境,这也是在Java中唯一一个得到运行时环境的方法。 // Runtime 类的大多数方法都是实例方法,也就是说每次进行运行时都要调用时getRuntime方法来获得与当前 Java 应用程序相关的运行时对象 Runtime run = Runtime.getRuntime(); run.exec("notepad"); //可以去执行程序的某个进程。 /* Runtime中的exit方法是退出当前JVM的方法,估计也是唯一的一个吧, 因为我看到System类中的exit实际上也是通过调用 Runtime.exit()来退出JVM的, 这里说明一下Java对Runtime返回值的一般规则(后边也提到了),0代表正常退出,非0代表异常中 止,这只是Java的规则, 在各个操作系统中总会发生一些小的混淆。*/ System.out.println("程序开始了吗"); run.exit(0); System.out.println("程序终止了吗"); } }
11、 BigDecimal类
类似于包装类,但是有些地方也有不同,比如不能自动装箱和拆箱,主要用于处理金钱和精确度较高的数据。
import java.math.BigDecimal; public class BigDecimalDemo { public static void main(String[] args) { //使用double:结果不精确 //加减乘除操作都不精确 System.out.println("0.09 + 0.01="+(0.09+0.01)); //使用BigDecimal:BigDecimal(double vale) BigDecimal num1 = new BigDecimal(0.09); BigDecimal num2 = new BigDecimal(0.02); System.out.println(num1.add(num2)); //结果还是不精确,因为传入double值的时候该值就不精确 //为了解决这一问题 使用BigDecimal(String vale) num1 = new BigDecimal("0.09"); num2 = new BigDecimal("0.01"); System.out.println(num1.add(num2)); } } 0.09 + 0.01=0.09999999999999999 0.1099999999999999970856645603589640813879668712615966796875 0.10
12、BigInteger类
java中的进制BigInteger十分的强大,而且好用,他可以表示任意大的整数,同时还可以进行进制转换,十分的方便,
代码示例:
import java.math.BigInteger;//导入该包 public class Demo { public static void main(String[] args) { String str = new BigInteger("15", 10).toString(16); System.out.println(str); } }
注:这里是将10进制的15转为16进制,依葫芦画瓢,便很容易实现转换;
13、 产生随机数的三种方法
import java.util.Random; import java.util.UUID; public class Test { public static void main(String[] args) { // 1. 产生数值类型的随机数经常使用这种 System.out.println((int)(Math.random()*21)+5); // 2. 产生随机数的第二种方式 Random r = new Random(); int randomValue = r.nextInt(10); //十以内的整型随机数,前包后不包。[0, 10) System.out.println(randomValue); // 3. 产生随机数的第三种方式(经常使用这种方式给文件命名,命名的时候要去除“-”,再拿来使用) //该方法产生36位,有四位是 "-" 。 //这种方式的随机数永远不会重复,因为有 System.currentTimeMillis()这个种子参与。 UUID rand = UUID.randomUUID(); String name = rand.toString().replace("-", ""); System.out.println(name); }
14、随机生成四位验证码
public static void main(String[] args) { int count = 0; char [] ch = new char[62]; for(char i ='0';i<='z';i++){ if(Character.isLetter(i)|Character.isDigit(i)){ ch[count] = i; count++; } } char []checkCode = new char[4]; for(int i = 0;i<checkCode.length;i++){ checkCode[i] = ch[(int)(Math.random()*62 )]; } System.out.println("随机生成四位验证码:"+new String(checkCode)); }
15、时间格式转换
public static void main(String[] args) { //1. 自定义格式转化标准格式 String day = "2011年11月11日 11时11分11秒"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); try { Date day1 = sdf.parse(day); System.out.println(day1); //Fri Nov 11 11:11:11 CST 2011 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String tt = sdf2.format(day1); System.out.println(tt); //2011-11-11 11:11:11 } catch (ParseException e) { e.printStackTrace(); } //2. 当前时间转换成指定格式 Date now = new Date(); SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); String dd = sdf1.format(now); System.out.println(dd); //2018年12月08日 18时37分26秒 }
16、日历类的常用方法和属性
Calendar cal = Calendar.getInstance();//获取日历对象 cal.set(Calendar.YEAR, 225);//直接设置日历中的字段值 cal.set(2018, 11,4); cal.add(Calendar.MONTH, 2);//对时间进行偏移 System.out.println(cal.get(Calendar.DAY_OF_WEEK));//一周中的第几天 一周中第一天从星期天开始 System.out.println(cal.get(Calendar.MONTH));//一年中的第几月份 月份从0开始 System.out.println(cal.get(Calendar.DAY_OF_MONTH)); System.out.println(cal.get(Calendar.DAY_OF_YEAR)); System.out.println(cal.get(Calendar.WEEK_OF_YEAR)); System.out.println(cal.get(Calendar.WEEK_OF_MONTH)); System.out.println(cal.get(Calendar.HOUR_OF_DAY)); System.out.println(cal.get(Calendar.SECOND)); System.out.println(cal.get(Calendar.MINUTE)); System.out.println(cal.get(Calendar.YEAR)); Date time = cal.getTime(); //将日历对象转化为日期对象 cal.setTime(time); //将日期对象的时间设置给日历对象
17、Math类其他常用的方法
System.out.println(Math.hypot(3,4));//求直角三角形斜边长 System.out.println(Math.sqrt(9));//开平方根号 System.out.println(Math.cbrt(27));//开立方根号 System.out.println(Math.pow(2, 8));//求第一个参数的第二个参数幂次方 System.out.println(bd1.add(bd2));//加 System.out.println(bd1.subtract(bd2));//减 System.out.println(bd1.multiply(bd2));//乘 System.out.println(bd1.divide(bd2));//除 除不尽的时候出现算术异常(ArithmeticException) Math.round() 四舍五入 Math.ceil()向上取整 Math.floor()向下取整 Math.random() 0-1随机数