泛型
泛型的定义
泛型可以解决数据类型的安全性问题,它主要的原理,是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化的时候只要指定好需要的类型即可。
泛型具体的类型指定是在创建对象的时候指定。
泛型的使用要求
在泛型的指定中,是无法指定基本数据类型的,必须设置成一个类,这样在设置一个数字的时候就必须使用包装类
泛型的定义语法
[访问权限] class 类名称<泛型类型1,泛型类型2,…泛型类型3>{ [访问权限] 泛型类型标识 变量名称 ; [访问权限] 泛型类型标识 方法名称(){} ; [访问权限] 返回值类型声明 方法名称(泛型类型标识 变量名称){} ; } |
通过泛型的定义的语法可以发现在定义类的时候就可以指定泛型了,而且泛型可以同时指定多个。
案例:
给坐标点使用泛型
package com.sram.entity; public class Point<T>{ private T pointX; private T pointY; public Point() { } public Point(T pointX,T pointY){ this.pointX=pointX; this.pointY=pointY; } public void setPointX(T pointX) { this.pointX = pointX; } public T getPointX() { return pointX; } public void setPointY(T pointY) { this.pointY = pointY; } public T getPointY() { return pointY; } @Override public String toString() { return "X坐标为"+this.pointX+",Y坐标为:"+this.pointY; } } |
public static void main(String[] args) { Point<Integer> point1=new Point<Integer>(23,34); System.out.println(point1); Point<Float> point2=new Point<Float>(23.3f,34.6f); System.out.println(point2); Point<String> point3=new Point<String>("北纬30度","东经120度"); System.out.println(point3); } |
X坐标为23,Y坐标为:34 X坐标为23.3,Y坐标为:34.6 X坐标为北纬30度,Y坐标为:东经120度 |
通过上面的代码设置,就达到了咱们之前讨论的那两个要求:
- 能够接受任何数据类型
- 保证数据类型的统一性
泛型的安全警告(了解)
如果使用一个泛型类创建对象,必须指定泛型对应的具体的数据类型,如果不定义则会出现警告:
public static void main(String[] args) { Point point1=new Point(23,34); System.out.println(point1); } |
X坐标为23,Y坐标为:34 |
此时出现警告这个警告在Java中就称为泛型的安全警告。
出现此警告的原因是没有指定泛型的具体数据类型,其实当一个泛型类在创建对象的时候没有指定泛型数据类型化就相当于直接使用Object类作为属性类型,这样话咱们设置泛型类就没有具体的意义。
在以后使用泛型类的时候尽量去指定泛型的数据类型。
通配符的使用
所谓的通配符其实就是使用一个符号来完成对应的多种数据类型的接收。在Java的泛型中有一个通配符”?”此通配符适合泛型类型的接收。
案例:
public static void main(String[] args) { Point<Integer> point1=new Point<Integer>(23,34); Point<Float> point2=new Point<Float>(23.3f,34.6f); Point<String> point3=new Point<String>("北纬30度","东经120度");
show(point1); show(point2); show(point3); } public static void show(Point<?> point3){//使用通配符?来接受参数 System.out.println(point3); } |
X坐标为23,Y坐标为:34 X坐标为23.3,Y坐标为:34.6 X坐标为北纬30度,Y坐标为:东经120度 |
受限泛型
在引用传递中,泛型操作中也可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object类。
设置泛型的上限
1、在申明对象的时候使用:
设置的语法:
类名称<? extends 类> 对象名称 |
案例:
public class Point<T extends Number>{//泛型的上线最大的为Number类 } |
上面的代码代表此类在创建对象的时候只能执行泛型类型为Number及其子类。也就是此时能执行的泛型类型对象是AtomicInteger, AtomicLong, BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, Short类及其子类,字符串无法使用了。
设置泛型的下限
1、在申明对象的时候使用
类名称<? super 类> 对象名称 |
案例:
public static void main(String[] args) { Point<Integer> point1=new Point<Integer>(23,34); Point<Number> point2=new Point<Number>(23.3f,34.6f); Point<String> point3=new Point<String>("北纬30度","东经120度"); show(point1); show(point2); show(point3); } public static void show(Point<? super Integer> point3){// System.out.println(point3); } |
|
此处设置了泛型的下限,设置了下限的话则只能输出当前类及其父类。
泛型接口
泛型接口的定义其实和泛型类的定义没有什么区别,只是定义类的时候使用class定义接口的时候使用interface定义。
案例:
public interface USB<T> {//泛型接口 } |
泛型接口的实现
方式一:直接在子类中指定泛型的数据类型
public interface USB<T> {//泛型接口 public abstract void show(T t); } |
public class Computer implements USB<String>{ @Override public void show(String t) { System.out.println(t); } } |
public static void main(String[] args) { Computer computer=new Computer(); computer.show("呵呵"); } |
呵呵 |
方式二:在子类中也是用泛型
public interface USB<T> {//泛型接口 public abstract void show(T t); } |
public class Computer<T> implements USB<T>{ @Override public void show(T t) { System.out.println(t); } } |
public static void main(String[] args) { Computer<String> computer=new Computer<String>(); computer.show("呵呵"); } |
呵呵 |
在开发过程中泛型接口也是会经常出现的,所以泛型接口的实现还需要加强练习。
泛型方法
所谓的泛型方法其实就是指的是方法的结构已经全部搭建完成,只是不知道具体的泛型类型是什么:
|
上面的这个方法就是一个泛型方法,只有当此方法所在的类在创建对象的时候才能确定此方法的具体功能。
多个泛型的设置
在Java中定义泛型接口或者泛型类的时候会遇到使用一种或者多种泛型的形式出现,那么怎么去定义多个泛型呢?
案例:
定义具有多个泛型的类
package com.sram.entity; public class Person<T,K> { private T name; private K age; private T sex; public Person() { } public Person(T name,K age,T sex) { this.age=age; this.name=name; this.sex=sex; } public void setAge(K age) { this.age = age; } public K getAge() { return age; } public void setName(T name) { this.name = name; } public T getName() { return name; } public void setSex(T sex) { this.sex = sex; } public T getSex() { return sex; } } |
创建多个泛型类的对象:
public static void main(String[] args) { Person<String,Integer> person=new Person<String, Integer>("张三", 23,"男"); System.out.println("姓名:"+person.getName()+",年龄:"+person.getAge()+",性别:"+person.getSex()); } |
姓名:张三,年龄:23,性别:男 |
枚举(了解)
在JDK 1.5之后,引入了一个新的关键字类型 —— enum,可以直接定义枚举类型
语法:
[public] enum 枚举类型名称{ 枚举对象1,枚举对象2,…,枚举对象n ; } |
案例:
public enum Color {//枚举类 RED,GREEN,BLUE;//此处的是Color类的三个对象 } |
在枚举类中的RED,GREEN,BLUE这三个就是枚举类Color类的三个对象。
public static void main(String[] args) { System.out.println(Color.BLUE); } |
********* ********* ********* BLUE |
此时验证了其实在枚举类中定义的不可改变的内容就是枚举的对象,通过对象可以获取对象名称,对象在枚举类中索引,获取对象中属性。
获取枚举类中的对象名称
public final String name() |
案例:
System.out.println(Color.BLUE.name());//获取对象的名称 |
BLUE |
获取枚举类中的对象位置
public final int ordinal() |
案例:
System.out.println(Color.BLUE.ordinal());//获取对象索引 |
2 |
枚举没有必要去死机,遇到了会回去枚举对象的值就可以了。
完整的案例:
定义一个枚举类,枚举类中有三个对象分别为RED,GREEN,BLUE,枚举类中有属性value,设置实行getter和setter方法,并通过有参构造方法创建对象。
package com.sram.enums;
public enum Color {//枚举类 RED("红色"),GREEN("绿色"),BLUE("蓝色");//此处的是Color类的三个对象 private String value; Color(String value){//自定义的有参构造 this.value=value; } public void setValue(String value) { this.value = value; } public String getValue() { return value; } } |
public static void main(String[] args) { System.out.println(Color.BLUE.name());//获取对象的名称 System.out.println(Color.GREEN.getValue());//通过枚举对象调用类中的方法 System.out.println(Color.BLUE.ordinal());//获取对象索引 } |
BLUE 绿色 2 |
注解(Annotation了解)
在之前学习了注释,注释是用来描述代码信息的,但是注解和注释不同,使用注解的话会给程序代码不同作用。
Annotation可以用来修饰类、属性、方法,而且Annotation不影响程序运行,无论是否使用Annotation代码都可以使用正常的执行
其实在每天编写代码的时候都会出现注解例如:
@Override public void show(T t) { System.out.println(t); } |
@Override就是注解。
在Java中提供的常见注解:
@Override:覆写的Annotation @Deprecated:不赞成使用的Annotation @SuppressWarnings:压制安全警告的Annotation |
三类注解中具体的内容如下:
No. | Annotation | JAVA中的声明 |
1 | @Override | @Target(value=METHOD) @Retention(value=SOURCE) public @interface Override |
2 | @Deprecated | @Documented @Retention(value=RUNTIME) public @interface Deprecated |
3 | @SuppressWarnings | @Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE}) @Retention(value=SOURCE) public @interface SuppressWarnings |
之后在程序的开发中再给大家介绍注解的实际功能,每个注解都有特定意义,在使用的时候能够明确其意义即可。
@Override主要是在方法覆写的时候使用,用于保证方法覆写的正确性。
@Deprecated注释的主要功能,是用来声明一个不建议使用的方法。如果在程序中使用了此方法的话,则在编译时将出现警告信息。
@SuppressWarnings注释的主要功能是用来压制警告,例如,之前讲解泛型操作的时候,如果在一个类声明时没有指明泛型的话,则肯定在编译时将产生,那么此时就可以使用@SuppressWarnings压制住这种警告。