泛型

泛型定义

在一个类型(类,接口,方法)之后,定义一个类型参数。

原生类型:类型后面没有指定具体的类型参数。

好处

使用泛型的好处在于,它在编译的时候进行类型安全检查,并且在运行时所有的转换都是强制的,隐式的,大大提高了代码的重用率。

语法

class Point<T>{}

通配符(?)

无界通配符(?)可以接受任何的类类型。

public void show(Point<?> p){}

(? extends 上限类)只能接受上限类和上限类子类,如只能接受数字类型,Byte,Short,Integer,Long,Float,Double

public void show(Point<? extends Number> p){}

(? super 下限类)下限,下限类和下限类的父类,Number和Number的父类

public void show(Point<? super Number> p){}

注意

Point<Object>不是Point<String>、Point<Integer>等的父类

public void add(Point<String> ps,Point<Object> po){//错误
po = ps
} public void add(Point<String> ps,Point<? extends Object> po){//正确

类型参数与通配符的区别

类型参数与 通配符的区别:
<T> 和 <?>
1.类型参数可以指定上限,也只能指定上限;
统配符可以指定上限,也可以指定下限;
2.类型参数 可以指定多个 上限;
通配符 只能指定一个上限;
3.类型参数 可以作为一种类型存在;
统配符不能表示 类型

泛型构造

//定义了一个泛型类
class PointN<T>{//类型参数 形式类型参数
private T x;
private T y;
//定义了一个泛型构造器
<E>PointN(E e){
System.out.println(e);
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
}
public class TestPoint2 {
public static void main(String[] args) {
// 指定具体的类型参数
PointN<String> p1 = new <Integer>PointN<String>();
//类型推断: 根据参数 的类型 自动推断出 构造的类型参数 是Integer类型
PointN<String> p2 = new PointN<String>();
} }

泛型方法

定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。

class Demo{
//泛型方法
public <E> void f(E e) {
System.out.println(e);
}
public <E> E ff(E e) {
return e;
}
public <E extends Number> void fff(E e) {
System.out.println(e);
//自动推断的方式
f("hello");
//指定的方式,显示,this
this.<String>f("hello");
}
}
public class TestPoint3 {
public static void main(String[] args) {
// 泛型方法应用
Demo d = new Demo();
//具体指定 泛型方法参数的类型
d.<String>f("hello");
//可以使用类型推断: 根据参数的类型 自动推断
d.f();
d.fff(); } }

泛型擦除

1.参数化类型:Point<String>,擦除后为原生类型Point

2.类型参数:用上界来替换

  • Point<T>:无界类型参数,用Object来替换

  • 类型参数有上限,用上限来替换。

  • 有多个上限,用第一个上限替换。

重载

class PointNew<T>{}
interface Info1{}
interface Info2{} class Demo1{
//为了实现重载
//生成的字节码文件中,泛型的信息被擦除了
public void f(String p) {}
public void f(PointNew<Integer> p) {}//擦除后:PointNew p
public <E> void f(E e) {}//擦除后:Object e
public <E extends Info1> void f(E e) {}//擦除后:Info1 e
public <E extends Info2 & Info1> void f(E e) {}//擦除后:Info2 e }

重写

class Parent{
//重写:参数父类中参数擦除后与子类中参数相同
public void f(PointNew<String> p) {}
}
class Child1 extends Parent{
public void f(PointNew<String> p) {}
}

泛型接口

//泛型接口
interface Info<T>{
void f(T t);
}
//在实现接口时 指定具体的类型参数
class InfoImpl1 implements Info<String>{
@Override
public void f(String t) {
System.out.println(t);
}
}
//在实现 接口时 不能确定类型
class InfoImpl2<T> implements Info<T>{
@Override
public void f(T t) {
System.out.println(t);
}
}
public class TestPoint5 { public static void main(String[] args) {
InfoImpl1 i1 = new InfoImpl1();
i1.f("hello");
InfoImpl2<String> i2 = new InfoImpl2<>();
i2.f("tom");
} }

比较器

Comparable

Comparator

对象进行自然方式排序,必须是实现了Comparable接口的。

Arrays.sort(数组);//默认 自然排序

Comparable<T> 泛型接口 比较器实现自然排序

Comparator<T> 泛型接口 外部比较器

 package day13;

 import java.util.Arrays;
import java.util.Comparator;
class Student implements Comparable<Student>{
private int age;
private int no;
public Student(int no,int age) {
this.age = age;
this.no= no;
}
public int getAge() {
return age;
}
public int getNo() {
return no;
}
@Override
public String toString() {
return "编号:"+no+",年龄:"+age;
}
/* @Override
public int compareTo(Object o) {
//this 与 o比较
//this.age o.age
Student stu = (Student)o;
//this.age stu.age return 0;
}*/
@Override
public int compareTo(Student o) {
// this.age o.age
//升序的方式
/*if(this.age > o.age ) {
return 1;//正数
}else if(this.age < o.age) {
return -1;//负数
}else {
return 0;//相等
}*/
return this.age - o.age;
}
}
//按照 编号升序排序
class NoComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// o1 和 o2比较
/* if(o1.getNo() > o2.getNo()) {
return 1;
}else if(o1.getNo() < o2.getNo()) {
return -1;
}else {
return 0;
}*/
return o1.getNo()- o2.getNo();
}
}
public class TestSort {
public static void main(String[] args) {
Student zhang = new Student(,);
Student wang = new Student(,);
Student zhao = new Student(,);
Student [] stus = {zhang,wang,zhao};
//Arrays.sort()按照自然方式排序的
// Arrays.sort(stus);
//1.自定义类 实现接口
// Arrays.sort(stus, new NoComparator());
//2.匿名内部类实现接口
Arrays.sort(stus,new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getNo() - o2.getNo();
}
});
//3 Lambda
Arrays.sort(stus,(s1,s2)->s1.getNo()-s2.getNo()); Arrays.stream(stus).forEach(System.out::println);
//--------------------------------------------
int [] arr = {,,,,};
Arrays.sort(arr);
Arrays.stream(arr).forEach(System.out::println);
//--------------------------------------------
String [] arrs = {"cc","dd","aa","ee"};
Arrays.sort(arrs);
Arrays.stream(arrs).forEach(System.out::println);
//------------------------------------------------
} }

枚举类型

语法

enum 枚举类型{

}
 package day13;

 import java.util.Scanner;

 //RGB
/*class Color{
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLUE = 3;
}*/
interface ColorInfo{
void fv();//抽象方法
}
enum Color{
RED(,"红色") {
@Override
void f() {
// TODO Auto-generated method stub }
},GREEN(,"绿色") {
@Override
void f() {
// TODO Auto-generated method stub }
},BLUE(,"蓝色") {
@Override
void f() {
// TODO Auto-generated method stub }
}; private Color(int no, String name) {
this.no = no;
this.name = name;
}
private int no;
private String name;
//抽象方法
abstract void f();
}
/*enum Color implements ColorInfo{
//定义枚举成员,对象,实例
RED(1,"红色"){
public void fv() {
System.out.println("红色的");
}
},GREEN(2,"绿色"){
public void fv() {
System.out.println("绿色的");
}
},BLUE(3,"蓝色"){
public void fv() {
System.out.println("蓝色的");
}
}; //public static final
private int no;//编号
private String name;//名字 private Color(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void f() {}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.no+","+this.name();
}
@Override
public void fv() {
// TODO Auto-generated method stub } }*/
public class TestEnum {
public static void main(String[] args) {
// System.out.println(Color.RED.getNo()+","+Color.RED.getName());
// System.out.println(Color.BLUE.getNo()+","+Color.BLUE.getName());
/* Color.RED.setName("红色");
System.out.println(Color.RED.getName());
Color.RED.f();*/
/* Color.RED.no = 11;
Color.GREEN.name = "绿色";
System.out.println(Color.RED.no);
System.out.println(Color.GREEN.name);*/ /* Scanner input = new Scanner(System.in);
System.out.println("输入一个颜色:");
String s = input.next();
Color co = Color.valueOf(s);
switch(co) {
case RED:
System.out.println("进行红色的操作");
break;
case GREEN:
System.out.println("进行绿色的操作");
break;
case BLUE:
System.out.println("进行蓝色的操作");
break;
}*/ //可以遍历枚举值
/* for(Color c: Color.values()) {
System.out.println(c.name());
System.out.println(c.ordinal());
}*/ /* // 类型不安全
int red = Color.RED;
int a = red +5;
System.out.println(a);
//意思不明确
System.out.println(Color.RED);*/
// System.out.println(Color.RED); } }

注意

1.所有的枚举类型的对象都在枚举类第一行显示定义出来。

2.对象默认是public static final的

3.枚举类的构造都是private的

4.枚举类继承自java.lang.Enum类

5.对于一个非抽象枚举类来说,都是final

一个枚举类的所有对象都实现了接口中的抽象方法,此枚举类就是抽象类,abstract的了

枚举类中定义抽象abstract方法,所有对象都需要实现此抽象方法,那么此枚举类是abstract的了

强制垃圾回收

class Person{

    @Override
protected void finalize() throws Throwable {
System.out.println("this---->"+this);
} }
public class TestGC { public static void main(String[] args) {
// 强制垃圾回收
Person per = new Person();
System.out.println(per);
per = null;//断开引用
System.gc();//强制通知垃圾回收器
// Runtime.getRuntime().gc();// } }

Day13 泛型的更多相关文章

  1. Java第十五天,泛型

    一.定义 泛型是一种未知的数据类型,即当我们不知道该使用哪种数据类型的时候,可以使用泛型. 泛型的本质是为了  参数化 类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型) ...

  2. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  3. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

  4. C#4.0泛型的协变,逆变深入剖析

    C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...

  5. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  6. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  7. C#泛型详解(转)

    初步理解泛型: http://www.cnblogs.com/wilber2013/p/4291435.html 泛型中的类型约束和类型推断 http://www.cnblogs.com/wilber ...

  8. C# 泛型

    C# 泛型 1.定义泛型类 在类定义中包含尖括号语法,即可创建泛型类: class MyGenericClass<T> { //Add code } 其中T可以遵循C#命名规则的任意字符. ...

  9. java8中lambda表达式的应用,以及一些泛型相关

    语法部分就不写了,我们直接抛出一个实际问题,看看java8的这些新特性究竟能给我们带来哪些便利 顺带用到一些泛型编程,一切都是为了简化代码 场景: 一个数据类,用于记录职工信息 public clas ...

随机推荐

  1. Java springmvc 统一异常处理的方案

    前言:为什么要统一异常处理?经常在项目中需要统一处理异常,将异常封装转给前端.也有时需要在项目中统一处理异常后,记录异常日志,做一下统一处理. Springmvc 异常统一处理的方式有三种. 一.使用 ...

  2. Microservices与DDD的关系

    Microservices(微服务架构)和DDD(领域驱动设计)是时下最炙手可热的两个技术词汇.在最近两年的咨询工作中总是会被不同的团队和角色询问,由此也促使我思考为什么这两个技术词汇被这么深入人心的 ...

  3. mac,macbook 连接蓝牙耳机播放音乐断断续续

    个人的情况是, mac本连的网线,用的无线鼠标, 屋里80多号人都在用笔记本,应该也有好多开着无线的东西 解决方法: mac 或macbook 连接蓝牙耳机播放音乐断断续续的原因, 在网上找了好多方法 ...

  4. 创建vue项目 webpack+vue

    # 全局安装 vue-cli $ npm install -g vue-cli # 创建一个基于 "webpack" 模板的新项目 根据提示填写项目信息 && 对项 ...

  5. CSS代码缩写

    盒模型代码简写 还记得在讲盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左.具体应用在margin和paddin ...

  6. css盒模型(Box Model)

    所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用. CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和 ...

  7. maven学习知识点汇总

    1. 2.maven自动建立目录骨架 首先进入目录结构:  PS C:\WINDOWS\system32> cd C:\Users\10563\Desktop\test 然后输入自动构建命令:  ...

  8. fuzz系列之afl

    afl 实战 前言 像 libFuzzer, afl 这类 fuzz 对于 从文件 或者 标准输入 获取输入的程序都能进行很好的 fuzz, 但是对于基于网络的程序来说就不是那么方便了. 这篇文章介绍 ...

  9. linux 软件包 rpm命令之安装、更新、卸载、依赖

    软件包分类1.源码包2.二进制包二进制包是源码包编译后产生的文件..exe文件是适用于windows平台的二进制包:RPM包适用于redhat系列的二进制包:deb包是适用于ubuntu平台的二进制包 ...

  10. 2Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

    public class TestException { public static void main(String[] args) { String str = "1"; fo ...