1.Java8的增强包装类
自动装箱:可以把一个基本类型变量直接赋给对应的包装类变量,或者赋给Object变量(Object是所有类的父类,子类对象可以赋给父类变量)
自动拆箱:允许直接把包装类对象直接赋值给对应的基本类型变量。
String类型转基本类型有两种方式:
int it1 = Integer.parseInt(intStr);
int it2 = new Integer(intStr);
基本类型转Stirng类型有两种方式:
String it = String.valueOf(5);
String it3 = 5+"";
包装类型的实例可以与数值类型相比较
包装类型为整型(byte\short\int\long\char),相同基本类型值赋值给包装类型变量后,包装类型做“==”比较,在0-127范围内相等,因为有缓存。基本类型为float或double时,引用变量不相等。
2.处理对象
- 打印对象和toString方法
toString方法是Object类提供的实例方法,可以根据需要重写toString方法获取感兴趣的信息
Public String toString(){}
// 效果一样
System.out.println(obj);
System.out.println(obj.toString());
-
“==”:
在比较两个基础类型的变量时,只要求值相等即返回true,并不要求变量的类型完全相同。
在比较两个引用类型变量时,只有他们指向同一个对象,才返回true.
“equals()方法:”
equals()方法是Object类中的实例方法,但这个方法判断两个对象相等的标准与==没有区别,所以没有太大的实际意义,若想达到类似“值相等”的目的,则可采用重写equals方法实现:
String类已经重写了Object类的equals方法,String的equals()方法判断两个字符串相等的标准是:只要两个字符串所包含的字符串序列相同,则返回true。
public boolean equals(Object obj) {
return (this == obj);
}
关于String的比较:
“hello”直接量与new String(“hello”)有什么区别?
当Java程序直接使用“hello”时,JVM将使用常量池管理这些字符串;当时用new String(“hello”)时,JVM先使用常量池管理“hello”直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象保存在堆内存中。换句话说,new String(“hello”)一共产生了两个字符串对象
String s1 = "疯狂Java";
String s2 = "疯狂";
String s3 = "Java";
String s4 = "疯狂"+"Java";
String s5 = "疯"+"狂"+"Java";
String s6 = s2+s3;
String s7 = new String("疯狂Java");
System.out.println(s1 == s4);//true
System.out.println(s1 == s5);//true
System.out.println(s1 == s6);//false
System.out.println(s1 == s7);//false
3.类成员
- 理解类成员
对于staice关键字而言,有一条重要规则:类成员(包括方法、初始化块、内部类、枚举类)不能访问实例成员(包括方法、初始化块、内部类、枚举类)。
- 单例(Singleton)类
一个类只能创建一个实例,该类被称为单例类。
几个注意的地方:
1. 构造器应该用private修饰(因为不能任意创建类的实例)
2. 应提供public static修饰的方法(本着良好封装的原则,应提供public方法用于创建类的实例,应该用static修饰(因为创建该对象的时候还没有对象))
3. 应定义static类型成员变量,类型为单例类。用于判断该单例类的对象是否已存在。(因为该成员变量需要通过static方法访问,所以该成员变量需用static修饰)
package chapter6.three;
/**
* Created by liudy on 16/8/30.
*/
//单例类:一个类始终有一个实例
class Singleton {
//使用一个变量来缓存曾经创建的实例
private static Singleton instance;
//对构造器使用private修饰,隐藏该构造器
private Singleton() {
System.out.println("单例类的构造器");
}
//提供一个静态方法,用于返回Singleton实例
//该方法可以加入自定义控制,保证只产生一个Singleton对象
public static Singleton getInstance() {
//如果instance为null,表明还不曾创建singleton对象
//如果instance不为null,表明已经创建singleton对象
//将不会重新创建新实例
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class SingletonTest {
/**
* @param args
*/
public static void main(String[] args) {
//创建Singleton对象不能通过构造器
//只能通过getInstance方法来得到实例
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);
}
}
4.final修饰符
- final成员变量
final修饰的成员变量必需由程序员显示的指定初始值(系统不会对final成员进行隐式初始化)
类变量:必需在静态初始化块或声明该类变量时指定初始值,而且只能在两个地方之一指定
实例变量:必需在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方之一指定
- final局部变量
既可以在定义时指定默认值,也可以不指定默认值。
- final修饰基本类型变量和引用类型变量的区别
//基本类型变量要求不能被改变
//引用类型要求引用的地址不改变,即一直引用同一个对象,但这个对象完全可以发生改变
- 可执行“宏替换”的final变量
“宏变量”的三个条件:
1. 使用final修饰
2. 定义该final变量时指定了初始值
3. 初始值在编译时就能被确定
final int a = 5;
//实际输出时直接为System.out.println(5);
System.out.println(a);
public class StringJoinTest {
public static void main(String[] args) {
String s1 = "疯狂Java";
String s2 = "疯狂"+"Java";
System.out.println(s1==s2);//true
String str1 = "疯狂";
String str2 = "Java";
String str3 = str1+str2;
System.out.println(s1==str3);//false
final String str4 = "疯狂";
final String str5 = "Java";
String str6 = str4+str5;
System.out.println(s1==str6);//true
}
}
- final方法
不可被重写,可以被重载
- final类
不可被继承
- 不可变类
不可变类: 创建该类的实例后,该实例的实例变量是不可变的
Java提供的8个包装类和java.lang.String类都是不可变类
如果需要创建自定义的不可变类,可遵守如下规则:
1. 使用private和final修饰成员变量
2. 提供带参数构造器用来初始化成员变量
3. 仅为该类的成员变量提供getter方法,不要为该类提供setter方法,因为普通方法无法修改final修饰的成员变量。
final修饰基本类型变量和引用类型变量的区别
基本类型变量要求不能被改变
引用类型要求引用的地址不改变,即一直引用同一个对象,但这个对象完全可以发生改变
package chapter6.four;
/**
* Created by liudy on 16/8/30.
* 不可变类中包含引用类型变量
*/
class Name{
private String firstName;
private String lastName;
public Name() {
}
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
//因为Human包含了一个引用类型的成员变量(Name类型),导致Human变成了一个可变类
public class Human {
private final Name name;
//下面的方式将导致Human类可变
// public Human(Name name) {
// this.name = name;
// }
//
// public Name getName() {
// return name;
// }
public Human(Name name) {
//设置name实例变量为临时创建的Name对象,该对象的firstName与lastName
//与传入name对象的firstName与lastName相同
this.name = new Name(name.getFirstName(),name.getLastName());
}
//返回一个匿名对象,该对象的firstName与lastName
//与传入name对象的firstName与lastName相同
public Name getName() {
return new Name(name.getFirstName(),name.getLastName());
}
public static void main(String[] args) {
Name n = new Name("悟空","孙");
Human h = new Human(n);
//获取Human对象的firstname值为"悟空"
System.out.println(h.getName().getFirstName());
n.setFirstName("八戒");
//将打印"八戒"
System.out.println(h.getName().getFirstName());
}
}
- 缓存实例的不可变类
待整理