核心类
1. 基本类型的封装类
java中八种基本数据类型都有其各自的封装类。
基本数据类型: byte、short、int、long、float、double、char、boolean;
对应的封装类:Byte、Short、Integer、Long、Float、Double、Character、Boolean;
基本数据类型与其对应的封装类由于本质的不同,具有一些区别:
int a = 10;
Integer aInteger = new Integer(a);
System.out.println("a = " + a + ", aInteger = " + aInteger);
1、基本数据类型只能按值传递,而基本的封装类按引用传递。
2、基本类型在栈中创建;而基本的封装类,对象的引用在栈中创建,对象在堆中创建。
3、基本类型由于在栈中,效率会比较高,但是可能会存在内存泄漏的问题。
封装类的作用
1、将一个字符串转换成基本数据类型
如: //构造方法
int a = new Integer("123");
//parseInt()静态方法方法
int b = Integer.parseInt("1335");
//这的String类型转换成int类型,其String类型所表示的必须是一个数
System.out.println("a = " + a + ", b = " + b);
2、将基本数据类型转换成字符串类型
如: //空字符串连接一个数值
String string1 = "" + 123;
//封装类Integer的静态方法
String string2 = Integer.toString(561);
//String类中的静态方法
String string3 = String.valueOf(580);
2. 装箱和拆箱
基本数据类型与其对应的封装类能够自动进行,其本质是Java自动装箱和拆箱的过程。
装箱:将基本类型数据值转换成对应的封装类对象,即将栈中的数据封装成对象存放到堆中的过程。
拆箱:装箱的反过程,即将封装的对象转换成基本类型数据值,将堆内存中的数据值存放到栈内存的过程。
如:
int a = 10;//基本类型
Integer aInteger = new Integer(10);//封装对象
Integer bInteger = 10; //装箱 编译器会自动展开:Integer bInteger = Integer.valueOf();
int b = aInteger;//拆箱
3. Object类
Object类是所有类的顶级父类。在Object中,需要注意的两个方法:equals()和toString()
1、equals()是判断指定对象与传入对象是否相等,与“==”有点区别。对于比较两个基本数据类型是否相等是直接使用“==”;对于比较两个引用数据类型是否相等时则有两种方式:
①、“==”运算符比较的是两个对象的地址是否相同,即引用的是同一个对象;
②、equals()方法通常用于比较两个对象的内容是否相同,在Object类中,equals()与“==”一样
Integer ax = new Integer(5); //新建ax对象
Integer bx = ax;
Integer cx = new Integer(5); //新建cx对象
System.out.println("ax = " + ax + ", bx = " + bx + ", cx = " + cx); //三者的值都一样
/**
* 由于ax与bx代表同一对象,所以存储的对象地址相同
*
* 基本数据类型没有equals()方法,但可以用“==”来进行内容比较,
* “==”在基本数据类型的比较原理是:
* 基本类型都是存储在栈里面的,
* 假设 在你 int a=3;后你 又 int b=3; 的时候,jvm会去栈里查找栈里有没有 3 这个数据
* 如果有就将存储 3 这个数据的地址赋值给 b;
* 如果没有,则新建一个 数据 3, 然后将数据 3 的地址赋值给 b
* 所以这里的 a 和 b 都存储 3 的地址,地址是一样 ;
* 故在基本数据类型里比较的也是地址;
* 假设这时 你又对 b 进行操作,如 b = 4; jvm再次查找栈,
* 栈里没有 4 这个数据,则 新建一个 4 的数据, 将4的地址赋值给b
* 注意:“==”永远是用来比较内存中的地址的,基本类型感觉上是在比较内容,实际上还是在比较地址!
*/
System.out.println("ax == bx : " + (ax == bx)); //true
/**
* ax与cx 代表不同对象,存储的对象地址不同
*
* 对于非基本类型,都是存在堆里面的动态分配内存,
* 所以每一次新建一个数据都会动态分配一个内存地址,
* 所以“==”的时候,当然内存地址是不一样的。
*/
System.out.println("ax == cx : " + (ax == cx)); //false
//Integer中的 equals()方法是用来比较的是两个值
System.out.println("ax.equals(bx) :" + ax.equals(bx));
System.out.println("ax.equals(cx) :" + ax.equals(cx));
/**
* Object 类的 equals 方法实现对象上差别可能性最大的相等关系;
* 即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,
* 此方法才返回 true(x == y 具有值 true)。
*
* 注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode
* 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
*
* 在Integer类中对equals()方法进行了重写,所以在Integer中是比较两者的值
*/
Integer i1 = 20;
Integer i2 = 20 ;
System.out.println(i1 == i2); // true
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4); // false
/**
* Integer i1 = 20; 其实是一个自动装箱的过程,
* 编译器会自动展开成:Integer i = Integer.valueOf(20); 详情可以看Integer.valueOf的源代码,
* 可以看到参数的值在IntegerCache.low(默认-128) 到 IntegerCache.high(默认127)范围内时(比如20),
* 会从IntegerCache.cache中直接取
* (此处参考Integer的内部类IntegerCache的源代码,如果不配置的话,默认是cache存储-128到127的Integer),
* 所以取到的都是同一个Integer的对象,因此相同。
* 而200不在-128到127范围内,所以会new 一个新的Integer,故不相同。
*/
2、toString()方法,由于每个类都是Object的子类,所以每个类都会自带一个toString()方法。
在Object类中:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* Object类中toString 返回的是 “当前对象的类名@哈希代码值”
*/
有些类,没有定义toString()方法,
当它的对象被 System.out.println(obj);时,
系统会自动调用对象的toString()方法,
所打印的就是 “当前对象的类名@哈希代码值”
4. 字符串类
在Java中字符串类主要有:String、StringBuffer、StringBuilder、StringTokenizer;字符串类型底层都是使用char数组进行实现。
1、String类
String类是Java里的一个常用类,是一个不可被继承的final类,而且字符串对象是一个不可改变对象。
/**
* 运行期计算得到的字符串会得到一个新的字符串。
*
* 这种现象是Java为了效率而赋予String的特殊性。
* 字符串是不可变的,字符串被分配了空间和初始值后值就不可变化。
* 一旦变化,就会放弃原有的对象而分配新的空间给变化后的字符串。
* 频繁地赋新值,会给程序运行效率带来极大影响,占用大量内存。
*/
String string2 = "Java12345";
String string1 = "Java" + 12345;
String string3 = new String("Java12345");
System.out.println("string1 :" + string1 + ", string2: " + string2 + ", string3 :" + string3);
System.out.println("string1 == string2 :" +(string1 == string2));//true
System.out.println("string1 == string3 :" +(string1 == string3));//false
/**
* 不推荐使用“==”来比较非主类型(像String类型)的对象值。
* 因为它通常不会得到期望的结果,可以说是不正确的。
* 因为“==”符号比较的是对象的首地址,所以“==”是无法比较对象的。
* 但是String有时候使用“==”能够得到正确的结果,
* 那是因为Java为了提高这个常用类型的效率和利用率,
* 将一些可以重复使用的字符串常量放到一个池中,尽可能地重用。
*
* 字符串池:
* 当定义一个 name=“hello”后,
* Java会先在字符串池中寻找是否已经存在“hello”这个字符串,
* 如果没有,则建立字符串“hello”对象,然后变量name指向这个地址。
*
* 而后定义一个新的字符串如果是编译时就能确定的话,
* 它会自动指向字符串池中的一个已存在的对象,
*
* 但是如果是运行期计算得出的,它将会分配新的空间给对象。
* 计算得来的字符串不知晓池中的任何对象,
* 但是可以使用intern方法使其指向字符串池中的对象。
* 同时指向池中同一个字符串对象,
* 使用“==”来比较肯定会返回true。池中String的hashCode是唯一的。
*
* 注意:
* 1、使用new操作创建的字符串对象不在池中。
* 2、计算得来的字符串不在池中。
* 3、只有编译期确定的对象直接被放入池中或指向池中对象。
* 4、使用“==”操作符号比较字符串时,必须值和hashCode值同时相等时,两个字符串才相等。
* 5、intern只会在字符串池中寻找匹配的对象,没有找到的话,自动将自己放入池内。
*/
2、StringBuffer类和StringBuilder类
StringBuffer创建的字符串是可变的,当使用StringBuffer创建一个字符串后,该字符串内容是可以通过append()、insert()、serCharAt()等方法进行改变,而字符串变量所引用的地址一直不变,最终调用它的toString()方法转换成一个String对象。
StringBuilder与StringBuffer类似也是创建一个可变字符串,不同的是StringBuffer是线程安全的,而StringBuilder没有实现线程安全,因此性能较好,常用的方法和StringBuffer一样。
5. Scanner类
Scanner类用来获取用户的输入。是一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。Scanner 使用分隔符模式将其输入分解为标记,默认情况下该分隔符模式与空白匹配。然后可以使用不同的 next 方法将得到的标记转换为不同类型的值。
//创建Scanner,从指定的输入流扫描
Scanner scanner = new Scanner(System.in);
System.out.println("Please input a world");
//设置输入完毕的符号,默认是空格
scanner.useDelimiter("\n");
String a = scanner.next();
System.out.println("a = " + a);
6. Math和Date类
Java中Math类包含常用的基本数学运算的方法,如指数、对数、平方和三角函数等。Math类提供的方法都是静态的,无需实例化,可直接调用。
/**
* Math类比较常用的方法,random()方法生成随机数,
* 其返回值是Double类型的,且数值范围在0~1之间
*/
System.out.println(Math.random());
//比较大 max()方法,比较小min()方法
System.out.println(Math.max(16, 10));
Java中Date类,用来表示时间的类。
Date date = new Date();
//获取系统当前时间
System.out.println(date);
//格式化日期的格式
String dateNow = new SimpleDateFormat("'Now Time :' y年 M月d日 H时m分s秒" ).format(date);
System.out.println(dateNow);