文章目录
1. Integer vs int
-
范围 -2^31 ~ 2^31-1
-
装箱(自动调用valueOf)/拆箱
-
new Integer(123) Integer.valueOf(123)
private static class IntegerCache static final int low = -128; static final int high; //Math.min(i, Integer.MAX_VALUE - (-low) -1); static final Integer cache[];//cache = new Integer[(high - low) + 1];
-
int 和 Integer 之间使用 == 比较,Integer 会自动拆箱,然后在与 int 进行比较
-
Integer 与 Integer 之间的比较
-
== 比较的是地址值
2. 关键字
-
private,protected,public, 默认 修饰类/成员变量/方法
-
final 修饰类/成员变量/方法
-
static 修饰类/成员变量/方法
static 方法:必须有实现,不能是抽象方法
static 静态内部类:不依赖于外部实例
StaticInnerClass staticInnerClass = new StaticInnerClass();
InnerClass innerClass = outerClass.new InnerClass();
初始化顺序:
父类(静态变量,静态语句块)
子类(静态变量,静态语句块)
父类(实例变量,普通语句块)
父类(构造函数)
子类(实例变量,普通语句块)
子类(构造函数)
-
内部类: https://www.runoob.com/w3cnote/java-inner-class-intro.html
-
assert
VM options 加上参数 -ea 即可开启
assert ; // true 程序继续执行, false: 抛出异常 java.lang.AssertionError
assert : // false: 抛出异常 + 异常信息
3.String
-
不可变
public final class String --> 不可被继承 private final char value[]; --> value初始化后指向的地址不能改变了(即不能引用其他数组)
好处:
缓存 hash, String 的 hashCode 只计算一次,算出结果赋值给 hash
String Pool 的需要(字符串常量池)
线程安全性
-
String a = “abc”; 经历了什么,将 “abc” 放入字符串常量池中,然后返回引用赋值给 a
-
StringBuffer,StringBuilder,String 比较
可变性
安全性
拼接字符串效率,why
-
String Pool
所处位置: java7之前,存在运行时常量池中,属于永久代. java7 移到了堆中.
原因: 永久代空间有限,大量使用字符串的场景下会导致 oom(outofmemoryerror)
String.intern()方法
-
new String(“abc”); 创建了几个对象
4. 参数传递
- 值传递, 复制一份地址/xxx 传递过去
5. 类型转换
-
1.1 字面值是 double,不能赋值给 float.
float f = 1.1;//error
float f = 1.1f; //true
-
1 字面量是 int 类型,不能下转为 short
short s = 1;
s = s+1;//error
s += 1;//true, ++/+=可以执行隐式类型转换
6. switch
- java7支持 String 对象的判断语句
- 不支持 long
7. 抽象类和接口
-
抽象类和普通类最大的区别是:抽象类不能被实例化
-
接口: java8之前,完全抽象的类,不能有实现方法,java8之后,可通过 default
-
比较: 从类的最外边往里面进行比较
-
abstract class A , interface A
-
成员变量: 接口中默认是 public,不允许定义为 private 或者 protected,字段默认是 public,static 和 final 的, 抽象类和普通类相同
3)构造函数:接口不能有构造函数, 抽象类可以有构造方法
4)方法:接口方法默认且只能为 public abstract , 抽象类中方法 和普通类相同 -> public static final void aa()
5)一个类可以实现多个接口,只能继承一个类(单继承)
6)接口:定义模块间的通信契约 抽象类:实现代码复用
-
8. 重写 vs 重载
-
重载 方法名称相同, 参数类型/个数/顺序 至少有一个不同,就是重载.
返回值不同,其余相同不算重载
-
重写:
访问权限大于父类, protected -> public
返回类型是父类/父类的子类型 Map -> HashMap
抛出异常是父类抛出异常/父类异常的子类型 Exception -> RuntimeException
9. Object
-
equals() 基本类型没有 equals 方法 : ==
-
hashCode()
覆盖 equals() 方法应当总是覆盖 hashCode() 方法.保证等价的两个对象, hashCode 值也相等
String 的 hashCode 和 equals
-
clone(): protected 方法 -> 一个类内部重写clone(),其他类才能直接调用该类实例的 clone()方法.
class A{} // 1)A中要重写 clone 方法 2) 实现 Cloneable 接口
A a = new A();
a.clone(); // error
浅拷贝:
拷贝对象和原始对象的引用是同一个
深拷贝:
拷贝对象和原始对象的引用不是同一个
10. 反射
-
Field:成员变量
-
Method:成员方法
-
Constructor:构造函数
-
获取对象的几种方式:
- source 阶段: Class.forName(“全类名”);
- class类对象阶段: 类名.class
- runtime阶段: 对象.getClass()
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过哪一种方式获取的Class对象都是同一个。
11. 异常
- error : jvm 层面的错误
- exception: 非运行时异常必须处理
12.注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
String desc() default "";
int length() default 0;
}
public class MyFieldTest {
@MyField(desc = "username",length = 8)
private String namename;
@Test
public void testMyField(){
System.out.println("into testMyField");
Class c = MyFieldTest.class;
for (Field field:c.getDeclaredFields()){
if (field.isAnnotationPresent(MyField.class)){
MyField annotation = field.getAnnotation(MyField.class);
System.out.println(field.getName()+"---"+annotation.desc()+"----"+annotation.length());
//namename---username----8
}
}
}
}
13. 实例化一个类
- (1)通过构造方法实例化一个类;
- (2)通过Class实例化一个类;
- (3)通过反射实例化一个类;
- (4)通过克隆实例化一个类;
- (5)通过反序列化实例化一个类;
- (6)通过Unsafe实例化一个类;
public class InstantialTest {
private static Unsafe unsafe;
static {
try{
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private static Stu unSerialize( String fileName) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
Stu stu5 = (Stu) ois.readObject();
ois.close();
return stu5;
}
public static void main(String[] args) throws Exception {
Stu stu1 = new Stu();
Stu stu2 = Stu.class.newInstance();
Stu stu3 = Stu.class.getConstructor().newInstance();
Object stu4 = stu1.clone();
Stu stu5 = unSerialize("xxx");
Stu stu6 = (Stu) unsafe.allocateInstance(Stu.class);
}
}
class Stu implements Cloneable, Serializable {
private String name;
public Stu(){
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}