内部类和泛型
1、内部类
内部类就是在类中的类。在源码中经常看到,但是源码中常见的都是静态内部类,最常见的类型就是数据类型A.数据类型B,也就是A.B
这种类型。
1、ThreadLocal.ThreadLocalMap;
2、Map中的各种静态结构等等;
3、获取得到单例对象
在以前学习java的时候,我们通常喜欢在一个类外面定义一个类,但是一个类中只能允许有一个public关键字修饰的类,那么另外的类通过不使用public关键字来进行修饰。
public class HungrySingle {
public static void main(String[] args) {
Hungry instance1 = Hungry.getInstance();
Hungry instance2= Hungry.getInstance();
System.out.println(instance1==instance2);
}
}
// HungrySingle类外来进行定义
class Hungry{
private static Hungry instance = new Hungry();
private Hungry(){}
public static Hungry getInstance(){
return instance;
}
}
成员内部类,既然名字是这样,那么就和一个类的成员没有什么太大的差距了,可以认为是地位是等同的。
例子1:
public class Outter {
private Integer id;
private String name;
public void showInner(){
// 创建内部类对象。在内部类中创建对象和在Test测试类中创建一致,但是要是在测试类中获取得到内部类比较麻烦,所以一般都不会 // 这样子去写而已。
Inner inner = new Inner();
inner.setId1(1);
inner.setName1("Inner");
System.out.println(inner);
}
public class Inner{
private Integer id1;
private String name1;
public void showOuter(){
// 访问自己内部的
System.out.println(id);
// 访问外部的
System.out.println(id1);
System.out.println(name1);
System.out.println(name);
}
public Integer getId1() {
return id1;
}
public void setId1(Integer id1) {
this.id1 = id1;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
@Override
public String toString() {
return "Inner{" +
"id1=" + id1 +
", name1=‘" + name1 + ‘\‘‘ +
‘}‘;
}
}
}
public class Test {
public static void main(String[] args) {
// 直接调用外部类中的方法
Outter outter = new Outter();
outter.showInner();
// 创建内部类对象。这种方式看起来极为别扭
Outter.Inner inner = new Outter().new Inner();
inner.setId1(111);
inner.setName1("inner");
System.out.println(inner.getId1());
}
}
例子2:
public class StaticSingleTest {
private StaticSingleTest(){}
// 定义一个方法来获取得到实例。这种方式使用起来有一个好处。什么时候用到了,什么时候就在进行加载。节约内存。
public static StaticSingleTest getInstance(){
return SinggleInstance.instance;
}
// 内部类可以访问到外部类中的一切成员。
// 静态内部类
static class SinggleInstance{
private static StaticSingleTest instance = new StaticSingleTest();
}
}
2、泛型
泛型的使用可以非常方便的简化我们在类型转换上的麻烦,在现在的开发中非常方便。减少使用强制类型转换。
常见的应用场景:集合类中以及我们在自定义响应给前端的响应对象Response类中,使用起来直接用。
用例子演示下:
public class TestFan {
private Object object;
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public static void main(String[] args) {
TestFan test = new TestFan();
test.setObject(new Boolean(true)); // 向上类型转换
Boolean var1 = (Boolean) test.getObject(); // 向下类型转换
System.out.println(var1);
test.setObject(new Float(1.23f)); // 向上类型转换
Float f = (Float) test.getObject(); // 向下类型转换
System.out.println(f);
}
}
这种方式频繁的使用真的是很麻烦,但是如果来使用泛型呢?可以看下对应代码
public class TestT<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public static void main(String[] args) {
TestT<Integer> t = new TestT();
t.setT(111);
Integer t1 = t.getT();
System.out.println(t1);
System.out.println("------");
TestT<Boolean> testT = new TestT<>();
testT.setT(false);
Boolean t2 = testT.getT();
System.out.println(t2);
}
}
这种方式使用起来比较优雅,想往类中放置什么对象就放置什么数据类型即可。
在对象中定义泛型,通常使用T;
在集合中定义泛型,通常使用E;
泛型还有对应的高级用法:
class 类名<T extends 数据类型>{};
等价于
class 类名<? extends 数据类型>{};
这里的数据类型可以是接口和类