首页 > 编程知识 正文

深入理解java泛型详解,java局部变量和成员变量

时间:2023-05-03 07:46:41 阅读:137235 作者:1019

通用命名约定

为了更好地理解泛型,还需要理解java泛型的命名约定。

为了与java关键字区分开来,java泛型参数用大写字母定义。 各种常用通用参数的含义如下

电子元素经常在Java集合(如列表、迭代器和集)中使用

表示k、V — Key、Value和Map的键值对

n—数字

T — Type、String、Integer等类型

s、u、V etc. - 2nd、3rd、4th类型使用与t相同的用法

上下限概要

公共流集(comparatorsuperecomparator ) {

新流计算机(this );

}

? 代表性类型必须是e的父母或e

Collection的添加:

增益(collectionextendsec ) )。

? 代表性的类型是e的子类或e

列表

List通常用作方法的参数类型或方法的返回类型。 其参数或返回值是未知类型,您确定吗? 是对象。 联想到多态性,就有点明白了。

以下代码例外。

List poems=new ArrayList (;

POEMS.add(lifeisasong );

? 指示保存在此List集合中的元素是未知类型。 在Java中,不能将对象放入未知类型的集合中。 通常:

包通用;

import java.util.ArrayList;

import java.util.List;

//*

* Created by zhoujie on 1/25/16。

*/

公共类第一次{

//*

*? 全部Object处理,处理所有类型

通过返回List的值,可以将其全部作为Object处理

* @param c

*/

publicstaticvoiddisplay{

for(intI=0; i c.size (; I ) {

//c.get(I )是Object类型的

system.out.println(c.get(I ) );

}

}

publicstaticvoidmain (string [ ] args ) {

List poems=new ArrayList (;

POEMS.add(lifeisasong );

POEMS.add(someonelikeyou );

POEMS.add(youaresobeautiful );

显示(poems );

}

}

列表扩展动画,通配符上限

Animal.java:

公共适配器类动画{

publicabstractvoidsing(performp;

}

Cat.java:

公共类cat extends animal {

@Override

公共语音信号(performp ) {

system.out.println('Hello,audience,I'm a Cat.' );

}

}

Dog.java:

公共类下载扩展动画{

@Override

公共语音信号(performp ) {

system.out.println('Hello,audience,I'm a dog.' );

}

}

Perform.java:

公共类性能{

公共语音性能(list animals ) {

for(animala:animals ) {

a.sing(this );

}

}

}

写下一个班测试一下上面的班吧。

公共类别测试{

>

public static void main(String[] args) {

List dogs = new ArrayList<>();

Perform p = new Perform();

dogs.add(new Dog());

p.perform(dogs); // 此处代码编译出现异常

}

}

List不能和perform中的参数 List animals对应起来,说明List并不是List的子类型,可以将Perform类的代码改成:

public class Perform {

public void perform(List> animals) {

for (Object o : animals) {

Animal a = (Animal)o;

a.sing(this);

}

}

}

这样的改进使用了泛型却还需要进行强制类型转换,略显繁琐。

继续改进Perform类:

public class Perform {

public void perform(List extends Animal> animals) {

for (Animal a : animals) {

a.sing(this);

}

}

}

终于引出了可爱的List extends Animal>,?表示的类型可以是Animal类型和Animal的子类。可以把Animal称为这个通配符(?)的上限(upper bound)。

和一开始讲的List>一样,List extends Animal> 通常也是当作函数的参数来指定,

public void addMonkey(List extends Animal> animals) {

// 下行代码出现编译错误

animals.add(0, new Monkey());

}

带 ?的泛型表达一般都当做方法参数或方法返回值来使用,也就是本笔记中讲述的泛型方法相关。

还有就是,如下代码:

public class Apple {

T col;

public static void main(String[] args) {

//类型只能是Number类型或Number的子类型

Apple ai = new Apple<>();

//编译错误

//Apple as = new Apple<>();

}

}

super E>通配符的下限

来看一段代码:

public static T copy(Collection super T> dest, Collection src){

T last = null;

for (T ele : src) {

last = ele;

dest.add(ele);

}

return last; //返回一个T类型的变量

}

/*

super Type> 通配符 ? 表示它必须是Type本身,或是Type的父类

*/

// 栗子

List ln = new ArrayList<>();

List li = new ArrayList<>();

li.add(2016);

// 此处可准确地知道最后一个被复制的元素是Integer类型

// 与src集合的元素类型相同

Integer ele = copy(ln, li);

在集合框架中的 TreeSet有一个构造器也用到了这种设定通配符下限的语法,

TreeSet(Comparator super E> c)

Comparator接口也是一个带泛型声明的接口:

public interface Comparator {

int compare(T fst, T snd);

}

看栗子:

Person类下面有一个子类 Student

class CompByName implements Comparator

{

@Override

public int compare(Person o1, Person o2) {

int temp = o1.getName().compareTo(o2.getName());

//如果姓名相等,根据年龄来排序

return (temp == 0) ? (o1.getAge() - o2.getAge()) : temp;

}

}

class CompByStuName implements Comparator

{

@Override

public int compare(Student o1, Student o2) {

int temp = o1.getName().compareTo(o2.getName());

//如果姓名相等,根据年龄来排序

return (temp == 0) ? (o1.getAge() - o2.getAge()) : temp;

}

}

/*

TreeSet(Comparator super E> comparator)

此处E类型是Person

下面的代码是编译不通过的

看TreeSet的构造器(Comparator super E> comparator)

根据下面代码的声明,E是Person类型,?表示的类型须是Person类型或Person的父类

而CompByStuName()是Comparator类型的

Student是Person的子类,根据TreeSet(Comparator super E> comparator)的约定所有就编译通不过啦

正确的:

TreeSet persons = new TreeSet<>(new CompByName());

TreeSet students = new TreeSet<>(new CompByName());

TreeSet students1 = new TreeSet<>(new CompByStuName());

*/

TreeSet persons = new TreeSet<>(new CompByStuName());

//没有指定泛型,add()中的形参就是Object

persons.add(new Person("jiaobuchong", 22));

persons.add(new Person("mesi", 21));

persons.add(new Person("活泼的小白菜", 23));

定义泛型接口

public interface World {

void show(T t);

}

实现上面的接口:

//实现方式1:

public class WorldImpl implements World {

public void show(String t) {

System.out.println(t);

}

}

//实现方式2:

public class WorldImpl implements World {

public void show(T t) {

System.out.println(t);

}

}

测试:

//实现方式1的测试

World w = new WorldImpl();

w.show("hello, girl");

//实现方式2的测试

World w1 = new WorldImpl();

w1.show("hello, jiaobuchong");

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。