Java基础
2020-12-15 16:16:30 0 举报
AI智能生成
Java基础
作者其他创作
大纲/内容
关键字
final
1. 数据 : 声明数据为常量,可以是编译时常量 ,也可以是运行时被初始化后不能被改变的常量
对于基本类型, final是数值不变
对于引用类型,final使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的
对于基本类型, final是数值不变
对于引用类型,final使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的
2.方法 : 声明方法不能被子类重写 .
private方法隐式的被指定为final,如果在子类中定义的方法和基类中的一个private方法签名相同,
此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法
private方法隐式的被指定为final,如果在子类中定义的方法和基类中的一个private方法签名相同,
此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法
3.类 : 声明类不允许被继承
static
静态变量
静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,
可以直接通过类名来访问它, 静态变量在内存中只存在一份.
可以直接通过类名来访问它, 静态变量在内存中只存在一份.
实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死
静态代码块
静态代码块在类初始化时运行一次
静态内部类
非静态内部类依赖于外部类的实例,也就是说需要先创建外部类实例,才能使用这个实例去创建的非静态内部类
而静态内部类不需要.
而静态内部类不需要.
静态内部类不能访问外部类的非静态变量和方法
静态导包
在使用静态变量和方法时不用再指名ClassName,从而简化代码,但可读性大大降低
初始化顺序
静态变量和静态代码块优先于实例变量和普通代码块,静态变量和静态代码块的初始化顺序取决于它们在代码中的顺序
存在继承的情况下,初始化顺序为:
父类(静态变量、静态语句块)
子类(静态变量、静态语句块)
父类(实例变量、普通语句块)
父类(构造函数)
子类(实例变量、普通语句块)
子类(构造函数)
父类(静态变量、静态语句块)
子类(静态变量、静态语句块)
父类(实例变量、普通语句块)
父类(构造函数)
子类(实例变量、普通语句块)
子类(构造函数)
Object通用方法
equals()
1.等价关系
两个对象具有等价关系需要满足五个条件
1.等价关系
两个对象具有等价关系需要满足五个条件
自反性
x.equals(x); // true
对称性
x.equals(y) == y.equals(x); // true
传递性
if (x.equals(y) && y.equals(z))
x.equals(z); // true;
x.equals(z); // true;
一致性
多次调用 equals() 方法结果不变
多次调用 equals() 方法结果不变
x.equals(y) == x.equals(y); // true
与null的比较
对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false
对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false
x.equals(null); // false;
2.等价与相等
对于基本类型, == 判断两个值是否相等,基本类型没有equals()方法
对于引用类型, ==判断两个变量是否引用同一个对象,而equals()判断引用的对象是否等价.
Integer x = new Integer(1);
Integer y = new Integer(1);
System.out.println(x.equals(y)); // true
System.out.println(x == y); // false
Integer y = new Integer(1);
System.out.println(x.equals(y)); // true
System.out.println(x == y); // false
3.实现
检查是否为同一个对象的引用, 如果是直接返回 true
检查是否是同一个类型,如果不是,直接返回false
将Object对象进行转型
判断每个关键域是否相等
public class EqualExample {
private int x;
private int y;
private int z;
public EqualExample(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EqualExample that = (EqualExample) o;
if (x != that.x) return false;
if (y != that.y) return false;
return z == that.z;
}
}
private int x;
private int y;
private int z;
public EqualExample(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EqualExample that = (EqualExample) o;
if (x != that.x) return false;
if (y != that.y) return false;
return z == that.z;
}
}
hashCode()
hashCode() 返回哈希值,而equals() 是用来判断两个对象是否等价. 等价两个对象 散列值一定相同
但是散列值相同的两个对象不一定等价
但是散列值相同的两个对象不一定等价
toSting()
默认返回对象内存地址
clone()
1.cloneable
浅拷贝
拷贝对象和原始对象的引用类型引用同一个对象
深拷贝
拷贝对象和原始对象的引用类型引用不同对象
继承
访问权限
类可见表示其他类可以用这个类创建实例对象
成员可见表示其他类可以用这个类的实例对象访问到该成员
抽象类与接口
抽象类
抽象类和抽象方法都是用abstract 关键字进行声明.如果一个类中包含抽象方法,那么这个类必须声明为抽象类
抽象类和普通类最大的区别是,抽象类不能被实例化,只能被继承
抽象类和普通类最大的区别是,抽象类不能被实例化,只能被继承
接口
接口是抽象类的延伸 , 在Java8之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现
比较
从设计层面上看,抽象类提供了一种IS-A关系,需要满足里式替换原则,即子类对象必须能够替换所有父类对象.
而接口更像是一种LIKE-A 关系, 它只是提供一种方法实现契约 ,并不要求接口和实现接口的类具有IS-A关系
而接口更像是一种LIKE-A 关系, 它只是提供一种方法实现契约 ,并不要求接口和实现接口的类具有IS-A关系
一个类可以实现多个接口 , 但不能继承多个抽象类
接口的字段只能使用static 和final 而抽象类的字段没有限制
接口的成员只能是public 而抽象类的成员可以有多种访问权限
super
访问父类的构造函数:可以使用super()函数访问父类的构造函数,从而委托父类完成一些初始化的工作
访问父类的成员:如果子类重写了父类的某个方法.可以通过使用super 关键字来引用父类的方法实现
重写与重载
重写
存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法
子类方法的访问权限必须大于等于父类方法
子类方法的返回类型必须是父类方法返回类型或为其子类型
子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型
重载
存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型,个数,顺序至少有一个不同.
应该注意的是,返回值不同,其它都相同不算是重装,
应该注意的是,返回值不同,其它都相同不算是重装,
数据类型
基本类型
byte/8
char/16
short/16
int/32
float/32
long/64
double/64
boolean/8
包装类型
描述:基本类型都有对应的包装类型,基本类型与其对应的包装类型之间的赋值使用自动装箱与拆箱完成。
缓存池
描述 : 在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。否则,就创建一个对象存储相应的数据。
String
概览: String 被声明为 final,因此它不可被继承,
在java8中, String 内部使用char 数组存储数据
在java9之后,String类的实现改用byte数组存储字符串,同时使用coder来标识使用了那种编码
在java8中, String 内部使用char 数组存储数据
在java9之后,String类的实现改用byte数组存储字符串,同时使用coder来标识使用了那种编码
不可变的好处
1.可以缓存hash值 : 因为String 的 hash值经常被使用,
例如 String 用做 HashMap 的key. 不可变的特性可以使得 hash值也不可变,因此只需要进行一次hash运算
例如 String 用做 HashMap 的key. 不可变的特性可以使得 hash值也不可变,因此只需要进行一次hash运算
2. String Pool 的需要
如果一个 String 对象已经被创建过了,那么就会从String pool 中取得引用.只有String是不可变的,才可能使用Stringpool
如果一个 String 对象已经被创建过了,那么就会从String pool 中取得引用.只有String是不可变的,才可能使用Stringpool
3. 安全性
String 经常作为参数,String不可变性可以保证参数不可变
例如在作为网络连接参数的情况下 如果String是可变的,那么在网络连接过程中,String被改变,改变String的哪一方以为现在连接的是其它主机,而实际情况却不一定是
String 经常作为参数,String不可变性可以保证参数不可变
例如在作为网络连接参数的情况下 如果String是可变的,那么在网络连接过程中,String被改变,改变String的哪一方以为现在连接的是其它主机,而实际情况却不一定是
4.线程安全
String 不可变天生具备线程安全,可以在多个线程中安全的使用
String 不可变天生具备线程安全,可以在多个线程中安全的使用
String,StringBuffer and StringBuilder
可变性
String 不可变
StringBuffer 和 StringBuilder 可变
线程安全
String不可变,所以线程安全
StringBuilder 线程不安全
StringBuffer 线程安全,内部使用了 synchronize 进行同步
String Pool
字符串常量池 (String Pool) 保存所有字符串字面量,这些字面量在编译时期就确定. 不仅如此,还可以使用String的
intern()方法在运行过程中将字符串添加到String Pool中
intern()方法在运行过程中将字符串添加到String Pool中
示例:
String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2); // false
String s3 = s1.intern();
String s4 = s2.intern();
System.out.println(s3 == s4); // true
String s2 = new String("aaa");
System.out.println(s1 == s2); // false
String s3 = s1.intern();
String s4 = s2.intern();
System.out.println(s3 == s4); // true
String s5 = "bbb";
String s6 = "bbb";
System.out.println(s5 == s6); // true
String s6 = "bbb";
System.out.println(s5 == s6); // true
备注: 在Java7之前,StringPool 被放在运行时常量池中,它属于永久代 而在Java7,StringPool 被移到堆中.这是因为永久代的空间有限,在大量使用字符串的场景下会导致 内存溢出 错误
运算
参数传递 : Java的参数是以值传递的形式传入方法中, 而不是引用传递
float与double : Java 不能隐式执行向下转型, 因为这会使得精度降低
隐式类型转换 :使用 += 或者 ++ 运算符会执行隐式类型转换
0 条评论
下一页