泛型就是将类型进行参数化
泛型主要是 编译时期的一种机制,擦除机制,运行时不存在泛型的概念
存放数据时会进行数据类型的检查,取出时会自动完成数据类型的转换
1. 初始泛型(泛型类)
泛型数组的定义:
T[] t = (T[])new Object[10];
class AUM <T>{
T[] t = (T[])new Object[10];
public T gett(int pos){
return t[pos];
}
public void sett(int pos, T tt){
t[pos] = tt;
}
}
public class Test {
public static void main(String[] args) {
AUM<Integer> aum = new AUM<Integer>();
aum.sett(0, 10);
System.out.println(aum.gett(0));
AUM<String> aum2 = new AUM<String>();
aum2.sett(0,"hello");
System.out.println(aum2.gett(0));
}
}
之一泛型类在实例化对象时尖括号内为空或者不写尖括号时称为裸类型,此时泛型不起任何作用.
2. 泛型的上界
class AUM <T extends Comparable>{
}
class AUM <T extends Comparable<T>>{
public T fineMax (T[] t){
T max = t[0];
for(int i = 1; i < t.length;i++){
if (max.compareTo(t[i]) < 0){
max = t[i];
}
}
return max;
}
}
public class Test{
public static void main(String[] args) {
AUM<Integer> aum = new AUM<>();
Integer[] t = {1, 2, 3, 4};
System.out.println(aum.fineMax(t));
}
}
class APM <T extends Comparable<T>>{
public T finamax(T[] t){
T max = t[0];
for(int i = 0; i < t.length; i++ ){
if(max.compareTo(t[i]) < 0){
max = t[i];
}
}
return max;
}
}
class Person implements Comparable<Person>{
public int age = 0;
public Person (int age){
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class Test{
public static void main(String[] args) {
Person[] person = {new Person(18), new Person(19)};
APM<Person> apm = new APM();
System.out.println(apm.finamax(person));
}
public static void main1(String[] args) {
AUM<Integer> aum = new AUM<>();
Integer[] t = {1, 2, 3, 4};
System.out.println(aum.fineMax(t));
}
}
3. 擦除机制
如果不指定泛型的上界则上界默认为Object
程序运行时,不存在泛型的概念,泛型全部被擦除成为上界类型
4. 泛型方法
静态泛型方法
class PUA {
public static <T extends Comparable<T>> T finaMax(T[] t){
T max = t[0];
for(int i = 0; i < t.length; i++){
if (max.compareTo(t[i]) < 0){
max = t[i];
}
}
return max;
}
}
public class Test{
public static void main(String[] args) {
String[] array = {"jfiwagn", "jwoejf"};
System.out.println(PUA.<String>finaMax(array));
}
静态方法
class PUA {
public <T extends Comparable<T>> T finaMax(T[] t){
T max = t[0];
for(int i = 0; i < t.length; i++){
if (max.compareTo(t[i]) < 0){
max = t[i];
}
}
return max;
}
}
public class Test{
public static void main(String[] args) {
String[] array = {"jfiwagn", "jwoejf"};
PUA pua = new PUA();
System.out.println(pua.<String>finaMax(array));
}
5. 通配符
1. 通配符
用于给泛型类或者泛型方法实现多态时,将指定泛型的位置写成?
,如下代码:
class NUM <T>{
T t;
public void setNum(T t){
this.t = t;
}
public T getNum(){
return t;
}
@Override
public String toString() {
return "NUM{" +
"t=" + t +
'}';
}
}
public class Test{
public static void main(String[] args) {
NUM<String> num = new NUM();
num.setNum("String");
fun(num);
NUM<Integer> num2 = new NUM();
num2.setNum(10);
fun(num2);
}
public static void fun(NUM<?> num){
System.out.println(num.getNum());
}
注意:
- 用通配符的方法中不能修改泛型类中的变量
- 形参中使用通配符并不能用方法重载来代替,因为重载时不论泛型是哪种类型,都具有相同的擦除机制,擦除后两个方法是一摸一样的方法,并不能构成重载.
2. 通配符上限
通配符上限是对通配符的通配做出了限制,让他不那么通配
public static void fun(Plent <? extend Fuirt> temp){}
如上代码,能作为fun方法的形参只能是Fuirt类或者Fuirt的子类
class Plent <T extends Fuirt > {
T t;
public T getPlent(){
return t;
}
public void setPlent(T t){
this.t = t;
}
@Override
public String toString() {
return "Plent{" +
"t=" + t +
'}';
}
}
class Fuirt{
}
class Apple extends Fuirt{
}
class Banana extends Fuirt{
}
public class Test {
public static void main(String[] args) {
Plent<Apple> plent1 = new Plent<>();
plent1.setPlent(new Apple());
fun(plent1);
Plent<Banana> plent2 = new Plent<>();
plent2.setPlent(new Banana());
fun(plent2);
}
public static void fun (Plent <? extends Fuirt> temp){
System.out.println(temp.getPlent());
}
}
通配符上限一般用来读取,不能用来写入
3. 通配符下限
public static void fun (Plent<? extends Fuirt> temp)
传入的实参只能是Fuirt或者Fuirt的父类
class Food{
}
class Plent <T extends Food > {
T t;
public T getPlent(){
return t;
}
public void setPlent(T t){
this.t = t;
}
@Override
public String toString() {
return "Plent{" +
"t=" + t +
'}';
}
}
class Fuirt extends Food{
}
class Apple extends Fuirt{
}
class Banana extends Fuirt{
}
public class Test2 {
public static void main(String[] args) {
// Plent<Apple> plent1 = new Plent<>();
// plent1.setPlent(new Apple());
// fun(plent1);
// Plent<Banana> plent2 = new Plent<>();
// plent2.setPlent(new Banana());
// fun(plent2);
Plent <Fuirt> plent3 = new Plent<>();
plent3.setPlent(new Fuirt());
fun(plent3);
Plent<Food> plent4 = new Plent<>();
plent4.setPlent(new Food());
fun(plent4);
}
public static void fun (Plent <? super Fuirt> temp){
//temp.setPlent(new Food());
temp.setPlent(new Fuirt());
temp.setPlent(new Apple());
temp.setPlent(new Banana());
System.out.println(temp.getPlent());
}
}
注意:
- 传参为通配符下限时,可以进行写入,但是只能是Fuirt及其子类,Fuirt的父类不可以写入. 2.
fun方法中可以读取,但是必须直接输出,读取的数据不能用变量接收
6. 包装类
装箱:
将基本数据类型转换成包装类类型
//自动装箱
Integer i1 = 10;
//手动装箱
Integer i2 = new Integer(100);
Integer i3 = Integer.valueOf(1000);
拆箱:
将包装类类型转换成基本数据类型
//自动拆箱
Integer i4 = 0;
int i5 = i4;
//手动拆箱
float i6 = i4.floatValue();
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;