所谓自动装箱,就是可以把一个基本类型变量直接赋给对应的包装类变量;自动拆箱则反之
public class AutoBoxingUnBoxing{
public static void main(String []args){
//直接把一个基本类型变量赋给Integer对象
Integer inObj=5;
//直接把一个基本类型变量赋给Object对象
Object boolObj=true;
//直接把一个Integer对象赋值给int基本类型
int it=inObj;
}
}
二 基本类型变量与字符串之间的转换
利用包装类 的paseXxx()静态方法(除了Character 之外),Xxx(String s)构造器;
String intStr="123";
int it1=Integer.paseInt(intStr);
int it2=new Integer(intStr);
特例 Integer biga=128; Interger bigb=-128; biga==bigb ;//false (Integer 并放入了一个名为cached 数组中缓存起来 ,系统把一个-128~127之间的整数自动装箱成Integer实例)
三 处理对象
1 toString()的用法;自我描述的功能
class Apple{
private String color;
private double weight;
//提供有参数的构造器
public Apple(Stirng color,double weight){
this.color=color;
this.weight=weight;
}
public Stirng toString(){
return "一个苹果的颜色是"+color+“重量是” +weight;
}
}
System.out.println(new Apple("红色",5.68));//输出"一个苹果的颜色是红色,重量是”5.68;
2 ==和equals方法
public class EqualTest{
int it=65;
float fl=65.0f;
it==fl;//true
char ch='A';
it==ch;//true
String str1=new String("hello");
String str2=new String("hello")
str1==str2;//flase
str1.equals(str2);//true
"hello"==new EqualTest(); //由于String和EquaTest()类没有继承关系,编译错误
}
“hello”和new String("hello");JVM将会使用长量池来管理这些字符串;new String("hello") 一共产生类2个字符串对象
String s1="疯狂java";
Stirng s2="疯狂";
String s3="java";
String s4="疯狂"+“java”;
String s5="疯"+“狂”+“java”
String s6=s2+s3;
String s7=new String("疯狂java");
s1==s4;//true
s1==s5;//true
s1==s6;//flase
s1==s7;//flase
JVM保证常量池相同的字符串直接量只有一个,不会产生多个副本
重写equals()方法,提供自定义的相等标准
public boolean equals(Object obj){
//如果两个对象为同一个对象
if(this==obj)//后只有一条语句可以省略花括号
retrun true;
if(obj!=null&&obj.getClass()==Person.class){}
Person personObj=(Person)obj;
if(this.getIdStr().equals(personObj.getIdStr())){
retrun true;
}
}
return false;
3 理解类成员变量
public class NuaaAccessStatic{
private static void test(){
System.out.println("static修饰的类方法");
}
public static void main(String []args){
NullAccessStatic nas=null;
nas.test();
}
}
当使用实例来访问类成员时,实际上依然是委托给该类来访问类成员。因此即使某个实例为空,它也可以访问它所所属的类成员
4 单例类
class Singleton{
//使用一个类变量来缓存曾经创建的实例
private static Singleton sinleton;
//对构造器使用private修饰,隐藏该构造器;
private Singleton(){}
//提供一个静态的方法,用于返回Singleton实例
//该方法可以加入自定义控制,保证只产生一个Singleton
public static Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}
Singleton s1=Singleton.getInstance();//不能通过构造器创建Singleton对象,只能通过getInstance获得;
5 final 成员变量
final修饰的成员变量必须由程序员显式的指定初始值,如果不指定系统默认分配的都是0,null。。么有意义的
如果final修饰的成员变量已经赋值,就不可再改变该值;
final 成员变量
public class FinalVariableTest{
final int a=6;
final String str;
final int c;
final static duoble d;
{
str="Hello";合法
//a=9;//非法
}
final int age;
{
System.out.println(""+age);//未初始化,错误
age=8;
System.out.println(""+age);
}
}
final 修饰基本类型变量和引用类型变量的区别
当使用final修饰基本类型变量时,不能对基本类型变量重新赋值。但对于引用类型变量而言,它保存的仅仅是引用,final 只保证这个引用类型变量不能被改变;
即对象可以有变化
final int[] iArr={5,6,7,8};
iArr[2]=10;//合法
//iArr=null;//错误
6 可执行“宏替换”的final变量
final int a=5;
System.out.println(""a);
final修饰的一个重要用途就是定义“宏变量”,当定义final变量时就为该变量指定了初始值,编译器会把程序中所有用到该变量的地方直接替换该变量的值
final int a=5+2;
final double b=1.2/3;
final String str="疯狂"+“java”;
final String book =“疯狂java讲义”+99.0;
//调用类String.valueOf()方法,编译时无法确定;
final String book2="疯狂java讲义"+String.valueOf(99.0);
String s1="aabb";
String s2="aa"+"bb";
s1==s2;//true
String s3="aa";
String s4="bb";
String s5=s3+s4;
s1==s5;//false
无法在编译时确定s5的值,可将s3 s4用final修饰
7 final方法
final修饰的方法不可重写 ,可重载
如果是private的final方法子类定义一个与父类相同的方法则属于子类的新方法,不存在重写
8 final类
final类不可继承
9 不可变类
定义不可变类
1 使用final 和private修饰成员变量
2 仅为该类提供getter方法
3 提供带参数的构造器,用于根据传入参数来初始化类里的成员变量
4 如果有必要 重写hashCode()和equals()方法
缓存实例的不可变类
class CacheImmutale{
//使用数组缓存已有的实例
private static CacheImmutale[] cache=new Cachelmmutale[Max_SIZE];
private static int MAX_SIZE=10;
//记录缓存实例的位置,cache[pos-1]是最新缓存的实例
private static int pos=0;
private final String name;
private CacheImmutale(String name){
this.name=name;
}
public String getName(){
return name;
}
public static CacheImmutale valueof(String name){
//遍历已缓存的对象
for(int i=0;i<MAX_SIZE;i++){
//如果已有相同实例,则直接返回该缓存的实例
if(cache[i]!=null&&cache[i].getName().equals(name)){
return cache[i];
}
//如果缓冲已满
if(pos==MAX_SIZE){
//把缓存的第一个对象覆盖,即把刚刚生成的对象放在缓冲池的最开始位置
cache[0]=new CacheImmutale(name);
pos=1;
}else {
cache[pos++]=new CacheImmutale(name);
}
return cache[pos-1];
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null&&obj.getClass()==CacheImmutale.class){
CacheImmutale ci=(CacheImmutale)obj;
retrun name.equals(ci.getName());
}
retrun false;
}
public int hashCode(){
return name.hashCode();
}
}
}
CacheImmutale c1= CacheImmutale.valueof("hello");
CacheImmutale c2= CacheImmutale.valueof("hello");
c1==c2;//true
java Integer类采用相同处理策略
Integer int1=new Integer(6);
Integer int2=new Integer.valueof(6);
Integer int3=new Integer.valueof(6);
int1==int2;//false
int2==int3;//true
Integer int4=new Integer.valueof(200)
Integer int5=new Integer.valueof(200);
int4==int5;//false Integer只缓存到-127~128之间的值