JAVA基础疑点难点笔记
接口
- 接口不能被实例化,但是接口变量可以引用一个实现了接口的类的对象!
泛型
- public List fuck(T …) …
<T>是申明T为泛型,以区别于类名,List<T>才为返回类型
泛型类和参数化类型
在一个泛型类中,可以通过下面的方式实现:
获取泛型子类的实际类型
- List是泛型,List<String>是参数化类型。
- 之所以称List<String> 是参数化类型,是因为String类在List类中是被当作参数来使用的。
- 因此 getGenericSuperclass() 得到了泛型,若该泛型有实际参数(String类等),则可以转成 ParameterizedType (参数化类型)。
- getActualTypeArguments() 可以得到参数化类型的实际参数类型数组,之所以是数组,是因为诸如 Map<k, v> 等泛型的参数化类型会有多个实际参数类型。
- 得到Type后,还需要将其转化为Class。
public abstract class BaseDao <T> {
private Class<T> clazz = null;
{
//
Type type = this.getClass().getGenericSuperclass();
ParameterizedType paramType = (ParameterizedType) type;
Type[] typeArguments = paramType.getActualTypeArguments();
clazz = (Class<T>) typeArguments[0];
}
}
反射
- Class类中的getDeclaredField()函数是可以获取一个类的所有字段.
- Class类中的getField()函数只能获取类的public 字段
- Field类中的setAccessible(true)函数使得我们可以访问该类中所有的私有成员变量
- 加载完类后,在堆内存的方法中就产生了一个Class类型的对象(一个类只有一个Class对象),类的Class对象包含了该类的全部信息
注解
元注解
- 元注解的作用就是负责注解其他注解,共有四个
- @Target 用于描述注解的范围,即注解在哪用。
- @Retention 用于描述注解的生命周期,表示需要在什么级别保存该注解,即保留的时间长短。
- @Documented 说明该注解将被包含在Javadoc中。
- @Inherited 说明子类可以继承父类中的该注解。
类
类和抽象类、接口的继承、实现
- 实现接口或继承抽象类的子类必须实现接口的所有方法或抽象类的所有抽象方法。
- 接口中的所有方法均为抽象方法,抽象类中包含非抽象方法和抽象方法。
- 如果一个类实现了接口,那么该子类必须实现父接口的所有方法。如果一个类继承了抽象类,那么该子类必须实现抽象类的所有抽象方法。
- 若一个抽象类实现了接口,那么,该抽象类可以实现接口中的抽象方法,也可以不实现。
- 若一个普通的子类继承了抽象父类,该抽象的父类又实现了接口,那么,该普通的子类必须得重写,抽象父类中所有的抽象方法,并且,还必须得实现抽象的父类尚未实现的抽象方法。
- 接口中的默认方法可以不实现。
子类创建时不会先创建父类对象
- 在Java中,当创建一个子类对象时,是不会先创建父类对象的。但是创建子类对象时,会去先调用父类的构造函数。
继承时代码的编译顺序
一般来说,在涉及继承时,代码执行顺序如下:
1.执行父类的静态代码块
2.执行子类的静态代码块
3.执行父类的构造代码块
4.执行父类的构造函数
5.执行子类的构造代码块
6.执行子类的构造函数
内存分析
细节
equals()函数的使用以及和 ‘==’ 的区别
equals()的使用应该注意避免空指针异常;
String str = new String();
//这样子容易造成空指针异常
str.equals("字符串常量");
//应该写成
"字符串常量".equals(str);
String中重写了equals()方法,equals()比较的是两个String对象的内容相不相同,而‘==’ 则是比较两个对象的堆内存地址是否相同。
boolean, int, double, char等基本数据类型用 ‘==’,而Interger, String等对象和自己创建的类对象就使用equals(),如果是自己创建的对象,还应该根据自己的需求重写 equals() 和 hashCode() 方法。
HashMap的get()方法传的是源对象
调用HashMap的get()方法,传的是HashMap里储存的对象,不会复制多一份,也就是相当于C++中的传引用,对get()到的对象进行修改,HashMap中对应的对象也会发生改变。
他人文章链接:Java HashMap中get方法的原理
测试代码
public class test {
public static void main(String args[]) {
List<Integer>> map = new HashMap<>();
map.put(1, new LinkedList<>());
map.get(1).add(1);
map.get(1).add(2);
map.get(1).add(3);
map.get(1).add(4);
map.get(1).add(5);
map.get(1).forEach(System.out::println);
List<Integer> list = map.get(1);
list.remove(0);
list.remove(0);
System.out.println("------------------");
map.get(1).forEach(System.out::println);
}
}
结果为: