回顾:
1. 线程死锁问题: 锁之间嵌套了。
2. 线程通信:--wait()和notify()
3. wait和sleep的区别。
(1)来自的类不同,(2)一个需要唤醒,一个自动唤醒 (3)是否能释放锁资源 (4)wait只能用在同步代码中,而sleep可以用在任意位置。
4. 线程池:
种类:(1)固定线程数的线程池 (2)单一线程池 (3)可变长度的线程池 (4)延迟线程池。
阿里建议: ThreadPoolExecutor 原生的方式来创建线程池--灵活。
核心参数有哪些?
core: 核心线程数
max: 最大线程数
long: 等待时长
timeunit:等待的时间单位
blockQueue:等待队列
5. Lock手动锁----自动锁的区别。
目录:
1. 什么是泛型?
2. 为什么使用泛型?
3. 如何使用泛型?
4. 泛型通配符?
5.泛型的限制
6.泛型接口
7.泛型方法
技术细节:
1. 什么是泛型?
List<E>:这里的<E>就是泛型标志,Map<K,V>这里<K,V>也是泛型标记。
泛型:就是类再定义时无法确认类中成员的类型(属性,方法),而是类再创建时指定具体的数据类型。
2. 为什么使用泛型?
例子: 定义一个Point 点类,要求如下
-
它的坐标值可以是整数。x=15,y=25
-
它的坐标值也可以都是小数: x=15.5 y=25.5
-
它的坐标值也可以都是字符串类型: x="北纬15度" y="东经258度"
package demo01;
public class Point {
private Object x;
private Object y;//为什么使用Object,因为Object是所有类的父类,子类类型可以自动向父类类型转化
public Point() {
}
public Point(Object x, Object y) {
this.x = x;
this.y = y;
}
/**
* 获取
* @return x
*/
public Object getX() {
return x;
}
/**
* 设置
* @param x
*/
public void setX(Object x) {
this.x = x;
}
/**
* 获取
* @return y
*/
public Object getY() {
return y;
}
/**
* 设置
* @param y
*/
public void setY(Object y) {
this.y = y;
}
public String toString() {
return "Point{x = " + x + ", y = " + y + "}";
}
}
------------------------------
package demo01;
public class Test {
public static void main(String[] args) {
//整数坐标
Point p1 = new Point(25,36);
//小数类型
Point p2 = new Point(23.5,36);
//String类型
Point p3 = new Point("北纬788","东经122");
//字符串和整型
Point p4 = new Point("北纬122",36);
//多态向下转型
String x = (String) p4.getX();
String y = (String) p4.getY();
}
}
输出结果:
*上面使用Object接受任意参数,可能会出现数据类型安全问题。如何解决上述问题,由于我们无法再类定义时确定类中成员的数据类型,所以我们可以使用泛型来解决数据类型安全问题。
3. 如何使用泛型?
泛型可以解决数据类型的安全性问题,其主要原理是在类声明时通过一个==标识==表示类中某个属性的数据类型或者是某个方法的返回值及参数类型。这样在类声明或者实例化时只要指定好需要的类型即可。
语法:
public class 类名<T,E,B>{
private T a;
public T getA(){}
public void setA(T t){}
}
*使用泛型来解决Point类的安全问题
代码演示:
package demo02;
//T可以是任意的名称:T是type的简写
public class Point01<T> {
private T x;
private T y;
public Point01() {
}
public Point01(T x, T y) {
this.x = x;
this.y = y;
}
/**
* 获取
* @return x
*/
public T getX() {
return x;
}
/**
* 设置
* @param x
*/
public void setX(T x) {
this.x = x;
}
/**
* 获取
* @return y
*/
public T getY() {
return y;
}
/**
* 设置
* @param y
*/
public void setY(T y) {
this.y = y;
}
public String toString() {
return "Point01{x = " + x + ", y = " + y + "}";
}
}
-------------------------
package demo02;
public class Test01 {
public static void main(String[] args) {
Point01<Integer> p1 = new Point01<>(15,25);
Point01<Double> p2 = new Point01<>(15.2,25.2);
Point01<String> p3 = new Point01<>("沙雕","沙雕");
String x = p3.getX();
Integer x1 = p1.getX();//不会出现数据安全问题
//注意!!!泛型的类型必须指定为引用类型,不能使用基本数据类型
//如果我们在创建范型类对象时没有指定泛型----那么他就是object类型
}
}
注意:
!!!泛型的类型必须指定为引用类型,不能使用基本数据类型
拓展:
常见的基本数据类型
byte,short,int,long,float,double,boolean,char
他们的包装类除了int 为 Integer ,其他均为把首字母改为大写
4. 泛型通配符?
在开发中==对象的引用传递==是最常见的,但是如果在泛型类的操作中,在进行引用传递时泛型类型必须匹配才可以传递,否则是无法传递的。
*对象的引用传递和值传递。
代码演示:
*值传递
package demo04;
//泛型的通配符
public class Test {
//值传递:基本类型的传递--------参数的改变不影响外部的改变
public static void main(String[] args) {
int a = 20;
fun(a);
System.out.println("a==============="+a);//a=20
}
public static void fun(int a){
a=15;
}
}
代码演示:
*引用传递:传递的是地址
package demo04;
//泛型的通配符
class Info{
public int b;
}
public class Test {
public static void main(String[] args) {
Info i = new Info();
i.b = 15;
fun2(i);
System.out.println("bb======="+i.b);//25
}
//引用传递--传递的是地址
public static void fun2(Info i){
i.b=25;
}
}
拓展:
代码演示:
*泛型的引用传递
*通配符
package demo05;
//泛型的引用传递,要求数据类型匹配而且泛型也要匹配
public class Test05 {
public static void main(String[] args) {
Info<Integer> a = new Info<>(15);
Info<String > b = new Info<>("hello world");
fun(a);//可以传递泛型匹配
fun(b);//b不可以传递,泛型不匹配
}
//任意的泛型都可以传递过来,使用泛型通配符。?
public static void fun(Info<?> info){
info.show();
}
}
//泛型类
class Info<T>{
private T var;
public void show(T var) {
this.var = var;
}
public void show(){
System.out.println("var============="+var);
}
public Info() {
}
public Info(T var) {
this.var = var;
}
/**
* 获取
* @return var
*/
public T getVar() {
return var;
}
/**
* 设置
* @param var
*/
public void setVar(T var) {
this.var = var;
}
public String toString() {
return "Info{var = " + var + "}";
}
}
5.泛型的限制 (使用在方法的引用传递上)
在引用传递中,在泛型操作中也可以设置一个泛型对象的==范围上限==和==范围下限==。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型或者此类型的父类型。
语法:
public void 方法名(Info<? extends Number> info){
//传递参数的泛型必须是Number或者Number的子类
}
public void 方法名(Info<? super Number> info){
//传递参数的泛型必须是Number或者Number的父类
}
代码演示:
public class Test04 {
public static void main(String[] args) {
// Info<Integer> a=new Info<>(15);
// Info<String> b=new Info<>("Hello");
// Info<Number> c=new Info<>(25.5);
// fun2(a);
// fun2(b);//泛型的引用传递,要求数据类型匹配而且泛型也要匹配。
//
// fun2(c);
//
// Info<Object> d=new Info<>(258);
// fun3(c);
// fun3(a);
// fun3(b);
// fun3(d);
}
//限定泛型的上线:泛型的限制使用在方法的引用传递中。
public static void fun2(Info<? extends Number> info){
info.show();
}
//限定泛型的下限
public static void fun3(Info<? super Number> info){
info.show();
}
//任意的泛型都可以传递过来。 使用泛型通配符。?
public static void fun(Info<?> info){
info.show();
}
}
class Info<T>{
private T var;
public Info(T var) {
this.var = var;
}
public void show(){
System.out.println("var==============="+var);
}
public T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
}
6.泛型接口
List<E> ArrayList<E>
在JDK1.5之后,不仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口名称后面加上<T>, 格式如下:
[访问权限] interface 接口名称<泛型标识>{
}
泛型接口的实现类的方式有两种:
(1)在创建类时也声明泛型而且该泛型的标识必须和接口的标识一致。
(2)在类实现泛型接口时,指明该泛型的数据类型。
代码演示:
package demo05;
import java.util.concurrent.Callable;
public class Test05 {
}
interface USB<T>{
public void show(T t);
}
//在创建类时,也指定泛型要求必须和接口的泛型标志一致
class Upan<T> implements USB<T>{
@Override
public void show(T t) {
}
}
class Shu implements USB<String>{
@Override
public void show(String s) {
}
}
7.泛型方法
前面学习的所有泛型操作都是将整个类进行泛型化,但同样也可以在类中定义泛型化的方法。泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是泛型类。
public class Test05 {
public static void main(String[] args) {
Test05 t=new Test05();
String hello = t.fun("hello");
Integer fun = t.fun(15);
}
//泛型方法: <T>在方法的返回值前面多了个泛型标志
public <T> T fun(T t){
System.out.println("结果为:"+t);
return t;
}
}
总结:
-
泛型类: public class 类名<标志,标志.....>{}
-
通配符: ?
-
限制泛型类型: ? super Number(下限) ? extends Number (上线)应用场景(引用传递)
-
泛型接口: public interface 接口<标志,标志.....>{}
-
泛型方法: public <标志> 返回值 方法名(参数列表){}