1.什么是泛型
1.1背景:
JAVA推出泛型以前,程序员可以构建一个元素类型为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型,否则很容易引发ClassCastException异常。
1.2.概念:
Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。
1.3.好处:
类型安全
消除了强制类型的转换
1.4.类型:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(表示Java 类,包括基本的类和我们自定义的类)
K - Key(表示键,比如Map中的key)
V - Value(表示值)
N - Number(表示数值类型)
? - (表示不确定的java类型)
S、U、V - 2nd、3rd、4th types
2.泛型类、接口
2.1 泛型类
(1)使用语法
类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();
(2)Java1.7以后,后面的<>中的具体的数据类型可以省略不写
类名<具体的数据类型> 对象名 = new 类名<>(); 菱形语法
2.2泛型类注意事项:
泛型类,如果没有指定具体的数据类型,此时,操作类型是Object
泛型的类型参数只能是类类型,不能是基本数据类型
泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型
有Generic这个类
Generic strGeneric = new Generic,
Generic intGeneric = new Generic
intGeneric.getClass() == strGeneric.getClass(),
结果是true
package gengic;
public class Generic <T>{
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
package gengic;
public class Mainclass {
public static void main(String[] args) {
//泛型类在创建对象的时候,来指定操作的具体数据类型
Generic<String> test = new Generic<>("a");
String key = test.getKey();
System.out.println(key);
System.out.println("======");
Generic<Integer> test1 = new Generic<>(100);
int key2 = test1.getKey();
System.out.println(key2);
System.out.println("======");
// Generic<int> test1 = new Generic<>(100);
//泛型类,不支持基本数据类型
//在创建对象的时候,没有指定类型,将按照Object类型来操作
Generic generic = new Generic("ABC");
Object key1 = generic.getKey();
System.out.println(key1);
System.out.println("======");
//同一泛型类,根据不同的数据类型创建的对象不同,本质上是同一类型
System.out.println(test.getClass());
System.out.println(test1.getClass());
System.out.println( test.getClass()== test1.getClass());
}
}
运行结果:
a
======
100
======
ABC
======
class gengic.Generic
class gengic.Generic
true
可以结合后面的泛型擦除理解,泛型擦除之后 Generic < String > 和Generic< Integer >都是Generic类。
抽奖demo案列:
package gengic;
import java.util.ArrayList;
import java.util.Random;
public class Product<T> {
Random random = new Random();
//产品
private T product;
//奖品池
ArrayList<T> list = new ArrayList<>();//建立一个list存储数据
public void addProduct(T t) {//在addProduct的方法中添加数据到list里
list.add(t);
}
//抽奖
public T getProduct() {
return product = list.get(random.nextInt(list.size())); //取出list中的数据
}
}
package gengic;
public class GetProduct {
public static void main(String[] args) {
Product<String> getProductString = new Product<>();//生成新的对象
String[]data = {"iphone","shopping card","coffe"}; //String的数组对象
//给抽奖器填充数据
for (int i = 0; i < data.length; i++) {
getProductString.addProduct(data[i]);//遍历数据并调用addProduct方法添加生成对象的数据中
}
//抽奖
String product1 = getProductString.getProduct();//getProduct方法取出对象中的数据
System.out.println("抽出产品"+ product1);
System.out.println("=================");
Product<Integer> getProductInteger = new Product<>();//生成新的对象
int []data1 = {1000,2000,3000,4000}; //String的数组对象
//给抽奖器填充数据
for (int i = 0; i < data1.length; i++) {
getProductInteger.addProduct(data1[i]);//遍历数据并调用addProduct方法添加生成对象的数据中
}
//抽奖
int product2 = getProductInteger.getProduct();//getProduct方法取出对象中的数据
System.out.println("抽出产品"+ product2);
}
}
运行结果
抽出产品coffe
=================
抽出产品1000
2.3 从泛型类派生子类
子类也是泛型类,子类和父类的泛型类型要一致
package gengic;
public class Father <E>{
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
package gengic;
/*
* 泛型类派生子类,子类也是泛型类,那么子类的泛型标识要和父类一致
*
* */
public class FirstChild<T> extends Father<T> {
@Override
public T getValue() {
return super.getValue();
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
package gengic;
public class FatherMain {
public static void main(String[] args) {
FirstChild<String> test1 = new FirstChild<>();
test1.setValue("a");
System.out.println(test1.getValue());
}
}
运行结果:
a
子类不是泛型类,父类要明确泛型的数据类型
package gengic;
public class Father <E>{
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
package gengic;
/*
*
* 泛型类派生子类,如果子类不是泛型类,那么父类要明确数据类型
* */
public class SecondChild extends Father<Integer>{
@Override
public Integer getValue() {
return super.getValue();
}
@Override
public void setValue(Integer value) {
super.setValue(value);
}
}
package gengic;
public class FatherMain {
public static void main(String[] args) {
FirstChild<String> test1 = new FirstChild<>();//泛型类
test1.setValue("a");
System.out.println(test1.getValue());
System.out.println("===================");
SecondChild test2= new SecondChild();//普通类
test2.setValue(50000);
System.out.println(test2.getValue());
}
}
运行结果:
a
===================
50000
2.4泛型接口
泛型接口的定义语法:
interface 接口名称 <泛型标识,泛型标识,…> {
泛型标识 方法名();
}
2.5.泛型接口的使用
实现泛型接口的类不是泛型类
package gengic;
/*
* 泛型接口
* */
public interface Generator<T> {
T getValue();
}
package gengic;
/*
* 实现泛型接口的类不是泛型类
* */
public class FirstInterface implements Generator<String> {
@Override
public String getValue() {
return "hello,world";
}
}
package gengic;
public class MainClass1 {
public static void main(String[] args) {
FirstInterface test1 = new FirstInterface();
System.out.println(test1.getValue());
}
}
运行结果:
hello,world
泛型接口的实现类,是一个泛型类,那么要保证实现接口的泛型类泛型标识包含泛型接口的泛型标识
package gengic;
/*
* 泛型借口
* */
public interface Generator<T> {
T getValue();
}
package gengic;
/*
泛型接口的实现类,是一个泛型类,那么要保证实现接口的泛型类泛型标识包含泛型接口的泛型标识
* */
public class SecondInterface<T,E> implements Generator<T>{
private T value;
private E key;
public SecondInterface(T value, E key) {
this.value = value;
this.key = key;
}
public void setValue(T value) {
this.value = value;
}
public E getKey() {
return key;
}
public void setKey(E key) {
this.key = key;
}
@Override
public T getValue() {
return value;
}
}
package gengic;
public class MainClass1 {
public static void main(String[] args) {
FirstInterface test1 = new FirstInterface();
System.out.println(test1.getValue());
System.out.println("======");
SecondInterface<String,Integer> test2 = new SecondInterface<>("age",10);
String value = test2.getValue();
int key = test2.getKey();
System.out.println(value);
System.out.println(key);
}
}
运行结果:
hello,world
======
age
10
3.泛型方法
3.1.用法
泛型类
,是在实例化类的时候指明泛型的具体类型
泛型方法
,是在调用方法的时候指明泛型的具体类型。
3.2.语法:
修饰符 <T,E, …> 返回值类型 方法名(形参列表) { 方法体… }
3.3.说明:
public与返回值中间非常重要,可以理解为声明此方法为泛型方法。
只有声明了的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
< T >表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
package gengic;
import java.util.ArrayList;
import java.util.Random;
public class Product<T> {
Random random = new Random();
//产品
private T product;
//奖品池
ArrayList<T> list = new ArrayList<>();//建立一个list存储数据
public void addProduct(T t) {//在addProduct的方法中添加数据到list里
list.add(t);
}
//抽奖
public T getProduct() {
return product = list.get(random.nextInt(list.size())); //取出list中的数据
}
public ArrayList<T> getList() {
return list;
}
/**
* @Description 定义泛型方法
* @Param :list参数
* @Param :<E>泛型标识,具体类型,由调用方法的时候指定
* @return: <null>
* @Author: Amy
* @Date: 2023-01-04
*/
public <E> E getProduct(ArrayList<E> list){
return list.get(random.nextInt(list.size()));
}
}
package gengic;
import java.util.ArrayList;
/**
* @program: datastuct
* @description:test
* @author: Amy
* @create: 2023-01-04 12:39
**/
public class test {
public static void main(String[] args) {
Product<Integer> test3 = new Product<>();
int[] data2 ={100,200,300};
for (int i = 0; i < data2.length; i++) {
test3.addProduct(data2[i]);
}
//泛型类的成员方法的调用
Integer product3 = test3.getProduct();
System.out.println(product3);
System.out.println("====");
Product<Integer> test1 = new Product<>();
ArrayList<String> data = new ArrayList<>();
data.add("computer");
data.add("phone");
data.add("money");
//泛型方法的调用,类型是通过调用方法的时候来指定
String product1 = test1.getProduct(data);
System.out.println(product1+"\t"+product1.getClass().getName());
System.out.println("====");
//泛型方法的调用,类型是通过调用方法的时候来指定
Product<Integer> test2 = new Product<>();
ArrayList<Integer> data1 = new ArrayList<>();
data1.add(1000);
data1.add(2000);
data1.add(3000);
//泛型方法的调用,类型是通过调用方法的时候来指定
Integer product2 = test2.getProduct(data1);
System.out.println(product2+"\t"+product2.getClass().getName());
}
}
结果运行:
300
====
money java.lang.String
====
1000 java.lang.Integer
3.4 泛型方法与可变参数
/*泛型方法与可变参数*/
public static <E> void print(E...e){
for (int i = 0; i < e.length; i++) {
System.out.println(e[i]);
}
}
//测试
/*泛型方法与可变参数*/
test2.print(1,2,3,4);
运行结果:
1
2
3
4
3.5 静态的泛型方法,采用多个泛型类型
/**
* 静态的泛型方法,采用多个泛型类型
* @param t
* @param e
* @param k
* @param <T>
* @param <E>
* @param <K>
*/
public static <T,E,K> void printType(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());
}
3.6 泛型方法总结
- 泛型方法能使方法独立于类而产生变化
- 如果static方法要使用泛型能力,就必须使其成为泛型方法
4、类型通配符
4.1.什么是类型通配符
类型通配符一般是使用"?"代替具体的类型实参。
所以,类型通配符是类型实参,而不是类型形参。
问题:
解决方法
package gengic;
/**
* @description:
* @author: Amy
* @create: 2023-01-04 15:01
**/
public class Box<E> {
private E first;
public E getFirst() {
return first;
}
public void setFirst(E first) {
this.first = first;
}
}
package gengic;
/**
* @description:
* @author: Amy
* @create: 2023-01-04 15:09
**/
public class TestBox {
public static void main(String[] args) {
//类型通配符
Box<Number> box1 = new Box<>();
box1.setFirst(100);
showBox(box1);
Box<Integer> box2 = new Box<>();
box2.setFirst(300);
showBox(box2);
}
public static void showBox(Box<?> box){ //类型通配符,不具体指定数据类型,用?
Object first = box.getFirst();
System.out.println(first);
}
}
运行结果:
100
300
4.2.类型通配符的上限
语法:
类/接口<? extends 实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的子类类型
。
代码:
package gengic;
/**
* @description:
* @author: Amy
* @create: 2023-01-04 15:25
**/
public class Animal {
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Cat extends Animal{
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class MiniCat extends Cat{
}
package gengic;
import java.util.ArrayList;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Animaltest {
public static void main(String[] args) {
ArrayList<Animal> animals = new ArrayList<>();
ArrayList<Cat> cat = new ArrayList<>();
ArrayList<MiniCat> minicat = new ArrayList<>();
// showAnimal(animals); 报错的原因是泛型的通配符是Cat,包括其继承的子类MiniCat,但不包括父类的Animal
showAnimal(cat);
showAnimal(minicat);
}
// 泛型上限通配符,传递的集合类型,只能是Cat或Cat的子类
public static void showAnimal(ArrayList<? extends Cat> list){
//泛型的通配符上限是不允许填充数据
//list.addAll(new Cat());
for (int i = 0; i < list.size(); i++) {
Cat cat = list.get(i);
System.out.println(cat);
}
}
}
4.3.类型通配符的下限
语法:
类/接口<? super 实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的父类类型
。
代码:
package gengic;
/**
* @description:
* @author: Amy
* @create: 2023-01-04 15:25
**/
public class Animal {
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Cat extends Animal{
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class MiniCat extends Cat{
}
package gengic;
import java.util.ArrayList;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Animaltest {
public static void main(String[] args) {
ArrayList<Animal> animals = new ArrayList<>();
ArrayList<Cat> cat = new ArrayList<>();
ArrayList<MiniCat> minicat = new ArrayList<>();
showAnimal(animals);
showAnimal(cat);
//showAnimal(minicat);
}
// 泛型通配符下限,传递的集合类型,只能是Cat或Cat的父类Animal
public static void showAnimal(ArrayList<? super Cat> list){
//泛型通配符下限可以添加其子类的数据
list.add(new Cat());
list.add(new MiniCat());
for(Object o:list){
System.out.println(o);
}
}
}
案例:
代码:
package gengic;
/**
* @description:
* @author: Amy
* @create: 2023-01-04 15:25
**/
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Cat extends Animal{
public int age;
public Cat(String name, int age) {
super(name);
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class MiniCat extends Cat{
public int level;
public MiniCat(String name, int age, int level) {
super(name, age);
this.level = level;
}
@Override
public String toString() {
return "MiniCat{" +
"level=" + level +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
package gengic;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Animaltest {
public static void main(String[] args) {
TreeSet<Cat> treeSet = new TreeSet<>(new Com2());
// TreeSet<Cat> treeSet = new TreeSet<>(new Com1()); //TreeSet是下限通配符,所以可以
//按照字母的顺序排序
// TreeSet<Cat> treeSet = new TreeSet<>(new Com3());//Cat以及父类是可以的,子类是不可以
treeSet.add(new Cat("a",10));
treeSet.add(new Cat("c",5));
treeSet.add(new Cat("d",17));
treeSet.add(new Cat("b",11));
for(Cat cat :treeSet){
System.out.println(cat);
}
}
static class Com1 implements Comparator<Animal>{
@Override
public int compare(Animal o1, Animal o2) {
return o1.name.compareTo(o2.name);
}
}
static class Com2 implements Comparator<Cat>{
@Override
public int compare(Cat o1, Cat o2) {
return o1.age-o2.age;
}
}
static class Com3 implements Comparator<MiniCat>{
@Override
public int compare(MiniCat o1, MiniCat o2) {
return o1.level-o2.level;
}
}
}
运行结果:
//按照age的大小排序
Cat{age=5, name='c'}
Cat{age=10, name='a'}
Cat{age=11, name='b'}
Cat{age=17, name='d'}
代码:
package gengic;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author: Amy
* @create: 2023-01-04 15:27
**/
public class Animaltest {
public static void main(String[] args) {
// TreeSet<Cat> treeSet = new TreeSet<>(new Com2());
TreeSet<Cat> treeSet = new TreeSet<>(new Com1()); //TreeSet是下限通配符,所以可以
//按照字母的顺序排序
// TreeSet<Cat> treeSet = new TreeSet<>(new Com3());//Cat以及父类是可以的,子类是不可以
treeSet.add(new Cat("a",10));
treeSet.add(new Cat("c",5));
treeSet.add(new Cat("d",17));
treeSet.add(new Cat("b",11));
for(Cat cat :treeSet){
System.out.println(cat);
}
}
static class Com1 implements Comparator<Animal>{
@Override
public int compare(Animal o1, Animal o2) {
return o1.name.compareTo(o2.name);
}
}
static class Com2 implements Comparator<Cat>{
@Override
public int compare(Cat o1, Cat o2) {
return o1.age-o2.age;
}
}
static class Com3 implements Comparator<MiniCat>{
@Override
public int compare(MiniCat o1, MiniCat o2) {
return o1.level-o2.level;
}
}
}
运行结果:
//按照字母的顺序排序
Cat{age=10, name='a'}
Cat{age=11, name='b'}
Cat{age=5, name='c'}
Cat{age=17, name='d'}
5、类型擦除
5.1.概念
泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是泛型代码能够很好地和之前版本的代码兼容。那是因为,泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为–类型擦除。
5.2.分类:
1)无限制类型擦除
代码:
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 16:22
**/
public class Erasure<T> {
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
package gengic;
import java.lang.reflect.Field;
/**
* @author: Amy
* @create: 2023-01-04 16:23
**/
public class TestErasure {
public static void main(String[] args) {
Erasure<Integer> erasure = new Erasure<>();
Class<? extends Erasure> clz= erasure.getClass();
Field[] declareFields = clz.getDeclaredFields();
for(Field declareField:declareFields){
System.out.println(declareField.getName()+":"+declareField.getType().getSimpleName());
}
}
}
运行结果:
key:Object
2)有限制类型擦除
代码:
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 16:22
**/
public class Erasure< T extends Number> {
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
package gengic;
import java.lang.reflect.Field;
/**
* @author: Amy
* @create: 2023-01-04 16:23
**/
public class TestErasure {
public static void main(String[] args) {
Erasure<Integer> erasure = new Erasure<>();
//利用反射,获取Erasure类的字节码文件的Class类对象
Class<? extends Erasure> clz= erasure.getClass();
//获取所有的成员变量
Field[] declareFields = clz.getDeclaredFields();
for(Field declareField:declareFields){
//打印成员变量的名称和类型
System.out.println(declareField.getName()+":"+declareField.getType().getSimpleName());
}
}
}
运行结果:
key:Number
3)擦除方法中类型定义的参数
代码:
package gengic;
import java.util.List;
/**
* @author: Amy
* @create: 2023-01-04 16:22
**/
public class Erasure< T extends Number> {
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
/**
* 泛型方法
* @Author: Amy
* @Date: 2023-01-04
*/
public <T extends List> T show(T t){
return t;
}
}
package gengic;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author: Amy
* @create: 2023-01-04 16:23
**/
public class TestErasure {
public static void main(String[] args) {
// 获取所有方法
Method[] declaredFields = clz.getDeclaredMethods();
for(Method declaredMethod : declaredFields){
// 打印方法名和方法的返回值类型
System.out.println(declaredMethod.getName()+":"+ declaredMethod.getReturnType().getSimpleName());
}
}
}
运行结果:
getKey:Number
setKey:void
show:List
4)桥接方法
代码:
package gengic;
public interface Info<T> {
T info(T t);
}
package gengic;
/**
* @author: Amy
* @create: 2023-01-04 17:40
**/
public class InfoImpl implements Info<Integer> {
@Override
public Integer info(Integer value) {
return value;
}
}
package gengic;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author: Amy
* @create: 2023-01-04 16:23
**/
public class TestErasure {
public static void main(String[] args) {
//拿到字节码对象
Class<InfoImpl> infoClass = InfoImpl.class;
// 获取所有方法
Method[] infoImplMethods = infoClass.getDeclaredMethods();
for(Method infoImplMethod : infoImplMethods){
// 打印方法名和方法的返回值类型
System.out.println(infoImplMethod.getName()+":"+ infoImplMethod.getReturnType().getSimpleName());
}
}
}
运行结果:
info:Integer
info:Object
6.泛型与数组
泛型数组的创建
可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象
错误:
错误:
import java.util.ArrayList;
/**
* @author: Amy
* @create: 2023-01-04 18:11
**/
//型数组的创建
public class ArrList {
public static void main(String[] args) {
ArrayList[] list = new ArrayList[5];//原生数组
ArrayList<String>[] listArr = list ;//泛型数组
ArrayList<Integer> intList = new ArrayList<>();
intList.add(100);
list[0]=intList;
String s = listArr[0].get(0);
System.out.println(s);
}
}
报错原因:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at gengic.ArrList.main(ArrList.java:19)
Process finished with exit code 1
正确代码:
import java.util.ArrayList;
/**
* @author: Amy
* @create: 2023-01-04 18:11
**/
//型数组的创建
public class ArrList {
public static void main(String[] args) {
ArrayList<String>[] strlistArr = new ArrayList[5];
ArrayList<String> strList = new ArrayList<>();
strList.add("abc");
strlistArr[0]=strList;
String s = strlistArr[0].get(0);
System.out.println(s);
}
}
运行结果:
abc
可以通过java.lang.reflect.Array的newInstance(Class,int) 创建T[] 数组
案例:
代码:
import java.lang.reflect.Array;
/**
* @author: Amy
* @create: 2023-01-04 20:18
**/
public class Fruit<T> {
private T[] array;
public Fruit(Class<T> clz,int length){
// 通过Array。newInstance创建泛型数组
array = (T[]) Array.newInstance(clz,length);
}
//填充数组
public void put(int index,T item){
array[index] = item;
}
//获取数组元素
public T get(int index){
return array[index];
}
public T[] getArray(Fruit<String> fruit){
return array;
}
}
/**
* @author: Amy
* @create: 2023-01-04 20:25
**/
public class Test1 {
public static void main(String[] args) {
Fruit<String> fruit = new Fruit<>(String.class,3);
fruit.put(0,"apple");
fruit.put(1,"peach");
fruit.put(2,"banana");
System.out.println(Arrays.toString(fruit.getArray(fruit)));
String s = fruit.get(1);
System.out.println(s);
}
}
运行结果:
[apple, peach, banana]
peach
7、泛型和反射
反射常用的泛型类
Class
Constructor
代码:
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
//泛型和反射
// Class<Person> personClass = Person.class;
// Constructor<Person> constructor = personClass.getConstructor();
// Person person = constructor.newInstance();
//如果不使用泛型会在之后还需要再转类型
Class personClass = Person.class;
Constructor constructor = personClass.getConstructor();
Object o = constructor.newInstance();
}
}