基本数据类型包括:数值类型(7)和布尔类型
数值类型:byte,char,short,int,long,float,double
7个数值类型之间可以进行类型转换:自动转换,强制转换
自动转换:范围小的数值赋值给范围大的
强制:返回大的赋值给范围小的
引用类型向上转型:只要子类赋值给父类的时候可以
引用类型向下转型:只有当一个类他本质是那个类的实例,才可以强制转换回去,否则不可以
Person p = new Student()//student是person子类
Student s = (Student)p;//因为p本质就是student的实例,所以才可以强制转换
int a = 6;
float f =a;
int a = 6;
byte b =(byte)a;
对于表达式,其数据类型会被自动提升到与表达式最高等级操作数同样的类型
byte b =40;
char c = 'a';
int i=23;
double d = .314;
double result = b+c+i*d;
对于一个数字5默认是int类型,对于一个浮点数默认是double
byte a =3;
int b=a+5;//byte+int-->int
3.5是double 3.5f是float
核心,记住
==
对于如果两个操作数都是数值类型,那么**即使他们的数据类型不同,只要他们的值相等**,就是true
对于是引用类型,则只要他们两个是父子类型才可以进行比较,且两个引用必须指向同一 个对象才是true 基本数据类型不能和引用类型
用==比较,除非遇到了(基本数据类型的包装类)自动装箱和自动拆箱
int it = 65;
float f1 =65.0f;
System.out.println(it==f1);//true基本类型只要值相等就好,类型可不同
char ch='A';
System.out.println(f1==ch);//true
System.out.println(it==ch);//true
String a1=new String("hello");
String a2=new String("hello");
System.out.println(a1==a2);//false
instanceof运算符,【对象的引用 instanceOf 类】( 只有前面操作数的编译时类型是后面的类具有父子继承关系或者同类才可以比较)判断它本质是哪个类型的,作用是在**强制类型**转换之前,判断一个对象(运行时类型)是否是后一个类 的实例,是否可以成功转换.。用于判断前面的对象是否是后面的类或者其子类,实现类的实例。
/声明obj时使用Object类,则其编译类型是Object
//但obj运行时类型是String
Object obj = "hello";
//下面语句会返回true,Object与Object同类,可以比较,编译不报错,且String是Object的子类,返回true
System.out.println(obj instanceof Object);
//下面语句会返回true,Object与String有父子关系,可以比较,且String是String的类,返回true
System.out.println(obj instanceof String);
if(obj instanceof String){
String b = (String)obj;//因为obj是String的类或者子类或者实现类,可以向上转换
}
//下面语句会返回false,Object与Math有父子关系可以比较,但String不是Math的类,子类,实现类
System.out.println(obj instanceof Math);
equals()只能用来判断两个引用类型
Object的equals()跟引用类型的==没区别,都是看看两个引用类型是不是同个对象。
String对Object的equals()重写,只需要判断两个引用类型的内容是否相等。
Integer的equals()会先判断这个类是不是Integer的类或者子类,是的话再判断他们的内容是不是相等,是返回true
//Object
public boolean equals(Object obj) {
return (this == obj);
}
//Integer
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
核心,记住
基本数据类型的自动装箱与拆箱
Integer. valueOf会吧-128到127的数值使用缓存,左闭右闭,给出同一个对象,超过这个范围的每个数值都是新建一个对象,而当自动装箱就会调用这个,超过数值范围的都算每次是一个新对象,而new integer每次都是新建一个对象
Integer a = 4;
Integer b =Integer.valueOf(4);
int c =b.intValue();
最上面两句是一样的,因为第一句默认会去调用Integer.valueOf把数值4转换为对象
1 //自动装箱,会自己调用Integer.valueOf
2 Integer total = 99;
3
4 //自动拆箱,会自己调用intValue()转换为基本数据类型
5 int totalprim = total;
public class Main {
public static void main(String[] args) {
Integer i1 = 100;//Integer i1=Integer.valueOf(100);
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //true,自动装箱为对象,Integer.valueOf方法会范围为-128到127的数值只new一个对象,因此一直是同个对象
System.out.println(i3==i4); //false,Integer.valueOf方法超过范围的数值每次都会new一个对象
}
}
对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,我们事先就创建好一个大小为256的Integer数组SMALL_VALUES,所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了。
但是对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的。
总结一句就是:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样。
–double与float不管什么时候都会新建一个对象
1 public static Double valueOf(double d) {
2 return new Double(d);
3 }
public class Main {
public static void main(String[] args) {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2); //false
System.out.println(i3==i4); //false
}
}
public class Main {
public static void main(String[] args) {
Boolean i1 = false;
Boolean i2 = false;
Boolean i3 = true;
Boolean i4 = true;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//true
}
}
下面我们进行一个归类:
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
Boolean派别:只有true和false,每次值只要是true都会返回同一个对象,只要值都是false
都会返回同一个对象
下面对Integer派别进行一个总结,如下图:
当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。
//前面说过==不能 用于判断基本类型与引用类型,只能判断基本与基本,引用与引用,这里可以是因为基本与引用遇到==会把引用拆箱为基本,因此这里的==是两个基本的判断,也就是只判断值是否相等
1 Integer num1 = 400;
2 int num2 = 400;
3 System.out.println(num1 == num2); //true
//前面说过equals只能判断两个引用类型之间,因此这里是对基本进行装箱,integer的equals会先判断num1是不是num2的累或者子类,是的话在判断值是否相同
1 Integer num1 = 100;
2 int num2 = 100;
3 System.out.println(num1.equals(num2)); //true
1 @Override
2 public boolean equals(Object o) {
3 return (o instanceof Integer) && (((Integer) o).value == value);
4 }
Integer num1 = 100;
int num2 = 100;
Long num3 = 200l;
System.out.println(num1 + num2); //200,基本与引用遇到运算符会把引用拆箱,即变成两个基本的比较,就是不管类型是什么基本类型,只比较内容相等即可,这里变成int 200
System.out.println(num3 == (num1 + num2)); //true
System.out.println(num3.equals(num1 + num2)); //false,Long不是Integer类或者子类,返回false(包装类的equals是类型相等/是其子类且内容相等)
Integer num1 = 100;
Integer num2 = 200;
Integer num4 = 300;
Integer num5 = 300;
Long num3 = 300l;
System.out.println(num3 == (num1 + num2)); //true
System.out.println(num4 == (num1 + num2));//true,会拆封成基本类型之间的比较,值比较值
System.out.println(num4 == num5);//false,引用类型之间的比较,看看是否是同个对象
Integer num6=100;
Integer num7=100;
System.out.println(num6==num7);//true引用类型比较,但由于自动装箱有缓存,-128~127给出的 是同个对象,因此是同个对象