泛型的运用
1.泛型举例
1.泛型类,如果没有指定具体的数据类型,此时,操作类型是0bject
2.泛型的类型参数只能是类类型,不能是基本数据类型
3.泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型
泛型举例
package com.lb.generic.example;
import javax.lang.model.element.VariableElement;
import java.util.ArrayList;
import java.util.Random;
public class ProductGetter<T> {
private T product;
ArrayList<T> list=new ArrayList<>();
Random random=new Random();
public void addProduct(T t){
list.add(t);
}
public T getProduct(){
product=list.get(random.nextInt(list.size()));
return product;
}
}
测试:
package com.lb.generic.example;
public class TestProduct {
public static void main(String[] args) {
ProductGetter<String> productGetter = new ProductGetter<>();
String [] product={"产品1","产品2"};
for (String s : product) {
productGetter.addProduct(s);
}
String product1 = productGetter.getProduct();
System.out.println("获取到产品:"+product1);
}
}
2.泛型类的继承情况
1.泛型类的子类要保证和父类的泛型要一致
语法:class ChildGeneric<T> extends Generic<T>
package com.lb.generic.extenttest;
public class Parent<E> {
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
package com.lb.generic.extenttest;
public class ChildOne<T> extends Parent<T> {
@Override
public T getValue() {
return super.getValue();
}
}
2.子类不是泛型类,父类要明确泛型的数据类型
class ChildGeneric extends Generic<String>
package com.lb.generic.extenttest;
public class ChildTwo extends Parent<String> {
@Override
public String getValue() {
return super.getValue();
}
}
3.泛型接口
泛型接口声明语法
interface 接口名称〈泛型标识,泛型标识,…>{
泛型标 识方法名();
}
泛型接口的使用
1.实现类不是泛型类,接口要明确数据类型
2.实现类也是泛型类,实现类和接口的泛型类型要一致
package com.lb.generic.interfaces;
public interface Generator<E> {
E getName();
}
package com.lb.generic.interfaces;
public class TestOne implements Generator<String> {
@Override
public String getName() {
return "test Interface";
}
}
package com.lb.generic.interfaces;
public class TestTwo<T,M> implements Generator<T> {
private T name;
private M age;
public TestTwo(T name, M age) {
this.name = name;
this.age = age;
}
@Override
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
public M getAge() {
return age;
}
public void setAge(M age) {
this.age = age;
}
}
4.泛型方法
1.泛型类,是在实例化类的时候指明泛型的具体类型。比如创建一个集合(List<String> lsit=new ArrayList<>())
2.泛型方法,是在调用方法的时候指明泛型的具体类型。
声明泛型方法的语法
修饰符 <T,E, ...> 返回值类型方法名(形参列表) {
方法体...
}
1.public与返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
2.只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
3.<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
4.与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
package com.lb.generic.genericmethod;
import com.lb.generic.example.ProductGetter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class GengericMethod {
public <E> E getProduct(ArrayList<E> list) {
return list.get(new Random().nextInt(list.size()));
}
public static void main(String[] args) {
GengericMethod gengericMethod = new GengericMethod();
ArrayList<String> name = new ArrayList<>();
name.add("xiong");
name.add("bear");
String product = gengericMethod.getProduct(name);
System.out.println(product);
}
}
静态泛型方法
public static <T,E,K> void getType(T t,E e,K k){
System.out.println(t+"\t"+t.getClass().getSimpleName());
System.out.println(e+"\t"+e.getClass().getSimpleName());
System.out.println(k+"\t"+k.getClass().getSimpleName());
}
public static void main(String[] args) {
GengericMethod.getType(100,"java",true);
}
输出:
100 Integer
java String
true Boolean
泛型方法可变参数
public <E> void print(E... e){
for (E el : e){
System. out.println(e);
}
}
public static <E> void print(E... e){
for (E el : e){
System.out.println(el+"\t"+el.getClass().getSimpleName());
}
}
public static void main(String[] args) {
GengericMethod.print(100,"test",true,new Object());
}
输出:
100 Integer
test String
true Boolean
java.lang.Object@4a574795 Object
1.泛型方法能使方法独立于类而产生变化
2.如果static方法要使用泛型能力,就必须使其成为泛型方法
5.类型统配符(Type wildcard)
类型通配符一般是使用"?"代替具体的类型实参。
所以,类型通配符是类型实参,而不是类型形参。
package com.lb.generic.typewildcard;
public class TypeWildcard<E> {
private E test;
public E getTest() {
return test;
}
public void setTest(E test) {
this.test = test;
}
}
package com.lb.generic.typewildcard;
public class TestType {
public static void main(String[] args) {
TypeWildcard<Number> typeWildcard = new TypeWildcard<>();
typeWildcard.setTest(1000);
testType(typeWildcard);
TypeWildcard<String> wildcard = new TypeWildcard<>();
wildcard.setTest("1000");
testType(wildcard);
}
public static void testType(TypeWildcard<?> box) {
Object test = box.getTest();
System.out.println(test);
}
}
类型通配符的上限
语法:
类/接口<? extends 实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的子类类型。
package com.lb.generic.typewildcard;
public class Animal {
}
package com.lb.generic.typewildcard;
public class Dog extends Animal{
}
package com.lb.generic.typewildcard;
public class SiberianHuskyDog extends Dog{
}
package com.lb.generic.typewildcard;
import java.util.ArrayList;
public class TestAnimal {
public static void main(String[] args) {
ArrayList<Animal> animals=new ArrayList<>();
ArrayList<Dog> dogs=new ArrayList<>();
ArrayList<SiberianHuskyDog> hsq=new ArrayList<>();
showAnimal(animals);
showAnimal(dogs);
showAnimal(hsq);
dogs.addAll(animals);
dogs.addAll(hsq);
}
public static void showAnimal(ArrayList<? extends Dog> list) {
for (int i = 0; i < list.size(); i++) {
Dog dog = list.get(i);
System.out.println(dog);
}
}
}
类型通配符下限
语法:
类/接口<? super实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的父类类型。
package com.lb.generic.typewildcard;
import java.util.ArrayList;
import java.util.List;
public class LowLine {
public static void main(String[] args) {
ArrayList<Animal> animals=new ArrayList<>();
ArrayList<Dog> dogs=new ArrayList<>();
ArrayList<SiberianHuskyDog> hsq=new ArrayList<>();
showAnimal(animals);
showAnimal(dogs);
}
public static void showAnimal(List<? super Dog> list){
list.add(new Dog());
list.add(new SiberianHuskyDog());
for (Object o : list) {
System.out.println(o);
}
}
}
下限通配符(TreeSet)
package com.lb.generic.typewildcard;
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public Animal() {
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
package com.lb.generic.typewildcard;
public class Dog extends Animal{
public int age;
public Dog(String name, int age) {
super(name);
this.age = age;
}
public Dog() {
super();
}
@Override
public String toString() {
return "Dog{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
package com.lb.generic.typewildcard;
public class SiberianHuskyDog extends Dog{
public String color;
public SiberianHuskyDog(String name, int age, String color) {
super(name, age);
this.color = color;
}
public SiberianHuskyDog() {
super();
}
@Override
public String toString() {
return "SiberianHuskyDog{" +
"color='" + color + '\'' +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
package com.lb.generic.typewildcard;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
public class LowLine {
public static void main(String[] args) {
TreeSet<Dog> treeSet = new TreeSet<>(new Comparator1());
treeSet.add(new Dog("二哈",2));
treeSet.add(new Dog("二哈1",2));
treeSet.add(new Dog("二哈2",2));
treeSet.add(new Dog("二哈3",2));
treeSet.add(new Dog("二哈4",2));
for (Dog dog : treeSet) {
System.out.println(dog);
}
}
}
class Comparator1 implements Comparator<Animal> {
@Override
public int compare(Animal o1, Animal o2) {
return o1.name.compareTo(o2.name);
}
}
class Comparator2 implements Comparator<Dog> {
@Override
public int compare(Dog o1, Dog o2) {
return o1.age-o2.age;
}
}
class Comparator3 implements Comparator<SiberianHuskyDog> {
@Override
public int compare(SiberianHuskyDog o1, SiberianHuskyDog o2) {
return o1.color.compareTo(o2.color);
}
}
TreeSet构造器源码:下限通配符
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
6.类型檫除
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是,泛型代码能够很好地和之前版本的代码兼容。那是因为,泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为–类型擦除。
无限制类型檫除
package com.lb.generic.typeremove;
public class Erasure<T> {
private T test;
public T getTest() {
return test;
}
public void setTest(T test) {
this.test = test;
}
}
package com.lb.generic.typeremove;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class TypeDisapper {
public static void main(String[] args) {
Erasure<Integer> erasure = new Erasure<>();
Class<? extends Erasure> aClass = erasure.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName() + " " + declaredField.getType().getSimpleName());
}
}
}
有限制类型檫除
package com.lb.generic.typeremove;
public class Erasure1<T extends Number> {
private T test;
public T getTest() {
return test;
}
public void setTest(T test) {
this.test = test;
}
}
package com.lb.generic.typeremove;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class TypeDisapper {
public static void main(String[] args) {
Erasure1<Integer> erasure = new Erasure1<>();
Class<? extends Erasure1> aClass = erasure.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName() + " " + declaredField.getType().getSimpleName());
}
}
}
檫除方法中类型定义的参数
package com.lb.generic.typeremove;
import java.util.List;
public class Erasure1<T extends Number> {
private T test;
public T getTest() {
return test;
}
public void setTest(T test) {
this.test = test;
}
public <T extends List> T test(T t){
return t;
}
}
package com.lb.generic.typeremove;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class TypeDisapper {
public static void main(String[] args) {
Erasure1<Integer> erasure = new Erasure1<>();
Class<? extends Erasure1> aClass = erasure.getClass();
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println("方法名:"+method.getName()+" 返回值类型: "+method.getReturnType().getSimpleName());
}
}
}
桥接方法
package com.lb.generic.typeremove;
public interface testInfo<T> {
T info(T t);
}
package com.lb.generic.typeremove;
import java.lang.reflect.Method;
public class TestInfoImpl implements testInfo<Integer> {
@Override
public Integer info(Integer integer) {
return integer;
}
public static void main(String[] args) {
TestInfoImpl testInfo = new TestInfoImpl();
Class<? extends TestInfoImpl> aClass = testInfo.getClass();
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("方法名:"+declaredMethod.getName()+" "+declaredMethod.getReturnType().getSimpleName());
}
}
}
7.泛型与数组
可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象
可以通过java.lang.reflect.Array的newInstance(Class<T>, int)创建T[]数组
package com.lb.generic.array;
import java.lang.reflect.Array;
public class Demo<T> {
private T[] array;
public Demo(Class<T> tClass,int length){
array= (T[]) Array.newInstance(tClass,length);
}
public void put(int index,T item){
array[index]=item;
}
public T get(int index){
return array[index];
}
public T[] getAll(){
return array;
}
}
package com.lb.generic.array;
import java.util.ArrayList;
import java.util.Arrays;
public class ArrayAndGeneric {
public static void main(String[] args) {
ArrayList<String>[] arrayLists = new ArrayList[5];
Demo<String> objectDemo = new Demo<>(String.class,3);
objectDemo.put(0,"luoxiong");
objectDemo.put(1,"test");
objectDemo.put(2,"haha");
System.out.println(Arrays.toString(objectDemo.getAll()));
}
}
~~~java
T item){
array[index]=item;
}
public T get(int index){
return array[index];
}
public T[] getAll(){
return array;
}
}
package com.lb.generic.array;
import java.util.ArrayList;
import java.util.Arrays;
public class ArrayAndGeneric {
public static void main(String[] args) {
ArrayList<String>[] arrayLists = new ArrayList[5];
Demo<String> objectDemo = new Demo<>(String.class,3);
objectDemo.put(0,"luoxiong");
objectDemo.put(1,"test");
objectDemo.put(2,"haha");
System.out.println(Arrays.toString(objectDemo.getAll()));
}
}
到此结束!每天学习一个小技巧!哈哈哈
|