java中一共有8中基本类型,其中有4种整型(byte、short、int、long)、两种浮点类型(float、double)、1种字符类型char和1种用于表示真值的boolean类型。
包装类型:基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。
类型 | 存储要求 | 取值范围 | 包装类型 |
---|---|---|---|
int | 4字节 | -2147483648~2147483647 | Integer |
short | 2字节 | -32768~32767 | Short |
long | 8字节 | -9223378036854775808~9223372036854775807 | Long |
byte | 1字节 | -128~127 | Byte |
float | 4字节 | 好多好多 | Float |
double | 8字节 | 好多好多 | Double |
char | 2字节 | Character | |
boolean | true/false | Boolean |
包装器:有时需要将int这样的基本类型转换为对象,所有的基本类型都有一个与之对应的类,例如Integer类对应基本类型int。通常这些类称为包装器。
自动装箱:在往ArrayList中添加int类型的时候,编译器将会自动的将该int类型的数据转化为Integer类的对象,这种变换称为自动装箱。
自动拆箱:将一个Integer对象赋给一个int值时,将会自动拆箱。
(1)数据
用final修饰数据时,表示数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
对于基本类型,final使其数值不变。
对于引用类型,final使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
(2)方法
声明方法不能被子类重写。
Tip:private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。
(3)类
声明类不允许被继承。
(1)静态变量
又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份。
(2)静态常量
如:
public static final double PI = 1.14159265358979323846;
(3)静态方法
静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。
静态方法只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字,因此这两个关键字与具体对象关联。
(4)静态语句块
静态语句块在类初始化时运行一次。
public class A {
static {
System.out.println("123");
}
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
this是对象本身的一个引用,代表对象本身。可以理解为指向本对象的一个指针。
用法包括:一是指示隐式参数的引用,二是调用该类的其他构造器
例子如下:
(本例子就是隐式参数的引用的实现)
public Employee(String name,int salary){
this.name = name;
this.salary = salary;
}
Tip:这里提到了隐式参数,对应的还有显式参数。
显式参数是方法中传递进来的形参,如本例的name和salary。
隐式参数是方法前命名的参数,如employee类的name属性和salary属性。
super是用来调用超(父)类的方法、属性的。但super不能像this一样的理解为是一个对象的引用。比如不能将值super赋给另一个对象变量。仅仅只是一个特殊的关键字。
用法包括:一是调用超类的方法,二是调用超类的构造器。
例子如下:(本例就是调用超类构造器的实例)
public class Manager extends Employee{
private double bonus;
public Manager(String name,double salary,int year,int month,int day){
super(name,salary,year,month,day);
bonus = 0;
}
}
Java程序设计语言总是采用按值调用。
按值调用表示方法接受的是调用者提供的值。而按引用调用表示方法接受的是调用者提供的变量地址。
当方法参数为基本数据类型时,方法不会改变该参数的值。
当方法参数为对象时,可以改变原对象的某些属性。因为方法得到的是对象引用的副本,原来的对象引用和这个副本都引用同一个对象。
方法不能让一个对象参数引用一个新的对象。
Java不能隐式执行向下转型,因为这会使精度降低。
向下转型只能使用强制类型转换。
double x = 9.997;
int nx = (int)x;
String类的实例是一个字符串,String不是一个基本数据类型。String 被声明为 final,因此它不可被继承。
在 Java 8 中,String 内部使用 char 数组存储数据。
在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 coder 来标识使用了哪种编码。
1, 可变性
String 不可变
StringBuffer 和 StringBuilder 可变
2.,线程安全
String 不可变,因此是线程安全的
StringBuilder 不是线程安全的
StringBuffer 是线程安全的,内部使用 synchronized 进行同步
object类中的equals方法用于检测一个对象是否等于另外一个对象。
equals方法需要具有以下特性:
(1)自反性:对于任何非空引用x,x.equals(x)应该返回 true。
(2)对称性:对于任何引用x和y,当且仅当y.equals(x)返回true时,x.equals(y)返回true。
(3)传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,x.equals(z)也应该返回true。
(4)一致性:如果x和y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果。
(5)对于任何非空引用x,x.equals(null)应该返回false。
实现:
(1)检查是否为同一个对象的引用,如果是直接返回 true;
(2)检查是否是同一个类型,如果不是,直接返回 false;
(3)将 Object 对象进行转型;
(4)判断每个关键域是否相等。
对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。
对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
hashCode() 返回哈希值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价,这是因为计算哈希值具有随机性,两个值不同的对象可能计算出相同的哈希值。
字符串的散列码(哈希值)相同,因为字符串的散列码是由内容导出的。
在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象哈希值也相等。
它会返回表示对象值的一个字符串。
打印数组需要调用静态方法Arrays.toString();
打印多维数组需要调用Arrays.deepToString。
==的作用是判断两个对象的地址是不是相等,即判断两个对象是不是同一个对象。(基本数据类型= =比较的是值,引用数据类型= = 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等,它不能用于比较基本数据类型的变量。
重写equals方法时必须要重写hashcode方法。原因如下:
1,如果两个对象相等,则 hashcode 一定也是相同的
2,两个对象相等,对两个对象分别调用 equals 方法都返回 true
3,两个对象有相同的 hashcode 值,它们也不一定是相等的
4,因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖