Java中的泛型

你好啊!在本文中,我们将了解JavaGenerics、如何创建泛型类和方法、它的优点以及如何使用它们来提高代码的质量。

JavaGenerics是在JDK5.0中引入的,目的是减少bug,并在类型上增加一个额外的抽象层。泛型指参数化类型。JavaGenerics允许我们创建一个单独的类、接口和方法,这些类、接口和方法可以用于不同类型的数据(对象),这有助于我们重用代码。

泛型方法是用单个方法声明编写的方法,可以用不同类型的参数调用。

泛型还提供编译时类型安全,允许程序员在编译时捕获无效类型。

“重要的是要注意,Generics不适用于原语类型(int、Float、char等)。”

为什么是泛型?

假设我们想要在Java中创建一个列表来存储Integer;我们可以尝试编写:

List list = new LinkedList();
list.add(new Integer(1)); 
Integer i = list.iterator().next();

编译器会抱怨最后一行,因为它不知道返回什么数据类型,它需要显式的转换:

Integer i = (Integer) list.iterator.next();

现在,这个转换可能很烦人,我们知道这个列表中的数据类型是一个Integer。我们的代码也杂乱无章。如果程序员在显式转换中出错,则会导致与类型相关的运行时错误。

如果程序员能够表达他们使用特定类型的意图,并且编译器能够确保这种类型的正确性,那就容易多了。这是仿制药背后的主要想法。

现在让我们修改代码。

List<Integer> list = new LinkedList<>();

通过添加包含类型的操作符<>,我们将这个列表的专门化缩小到Integer类型,也就是说,我们指定将在列表中保存的类型。然后,编译器可以在编译时强制执行该类型。这可以增加显着的健壮性,并使程序更容易阅读。

我们可以创建一个可以与任何类型的数据一起使用的类。这种类称为泛型类。下面是如何在Java中创建泛型类:

class Main {
  public static void main(String[] args) {

    // initialize generic class with Integer data

    GenericsClass<Integer> intObj = new GenericsClass<>(5);
    System.out.println("Generic Class returns: " + intObj.getData());

    // initialize generic class with string data

    GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
    System.out.println("Generic Class returns: " + stringObj.getData());
  }
}

// create a generics class
class GenericsClass<T> {

  // variable of T type
  private T data;

  public GenericsClass(T data) {
    this.data = data;
  }

  // method that return T type variable
  public T getData() {
    return this.data;
  }
}

输出

Generic Class returns: 5
Generic Class returns: Java Programming

在这里,我们创建了一个名为GenericsClass的泛型类,这个类可以用于处理任何类型的数据。

class GenericsClass<T> {...}

这里,角括号内使用的T<>表示类型参数。在主类中,我们创建了GenericsClass的两个对象

IntObj-在这里,类型参数T被Integer替换。现在,GenericsClass处理整数数据。

String Obj-在这里,类型参数T被字符串替换。现在,GenericsClass处理字符串数据。

我们还可以创建一个可以与任何类型的数据一起使用的方法。这类被称为泛型方法。

下面是如何在Java中创建泛型类:

class Main {
  public static void main(String[] args) {

    // initialize the class with Integer data
    DemoClass demo = new DemoClass();

    // generics method working with String
    demo.<String>genericsMethod("Java Programming");

    // generics method working with integer
    demo.<Integer>genericsMethod(25);
  }
}

class DemoClass {

  // creae a generics method
  public <T> void genericsMethod(T data) {
    System.out.println("Generics Method:");
    System.out.println("Data Passed: " + data);
  }
}

输出

Generics Method:
Data Passed: Java Programming
Generics Method:
Data Passed: 25

因此,在上面的代码中,我们创建了一个名为genericsMethod的泛型方法。

public <T> void genericMethod(T data) {...}

我们可以通过将实际类型和括号中的实际类型放在方法名称之前来调用泛型方法。

demo.<String>genericMethod("Java Programming");

demo.<Integer>genericMethod(25);

我们可以在不包含类型参数的情况下调用泛型方法。例如,

demo.genericsMethod("Java Programming");

有界类型

让我们来看看有界类型。Type参数可以接受任何数据类型(基本类型除外)。

有界的意思是“受限”,我们可以限制可以被方法接受的类型。

如果我们只想对某些特定类型使用泛型(例如接受数字类型的数据或接受字符串类型的数据),那么我们可以使用有界类型。

在绑定类型的情况下,我们使用EXTEND关键字。

<T extends A>

这意味着T只能接受A的子类型的数据。

class GenericsClass <T extends Number> {

  public void display() {
    System.out.println("This is a bounded type generics class.");
  }
}

class Main {
  public static void main(String[] args) {

    // create an object of GenericsClass
    GenericsClass<String> obj = new GenericsClass<>();
  }
}

在上面的代码中,我们创建了一个名为GenericsClass的类。注意,GenericsClass表达式是用有界类型创建的。这意味着GenericsClass只能处理属于数字子类(Integer、Double等)的数据类型。

泛型优势

它促进代码重用:在Java泛型的帮助下,我们可以编写处理不同类型数据的代码。

public <T> void genericsMethod(T data) {...}

以上方法可用于对整数数据、字符串数据等执行操作。

类型安全

在编译时了解代码中的问题总是比让代码在运行时失败更好

泛型在出现编译时会出现错误,而不是在运行时出现错误。

// using Generics
GenericsClass<Integer> list = new GenericsClass<>();

在这里,我们知道GenericsClass只使用Integer数据。

如果我们尝试将Integer以外的数据传递给这个类,程序将在编译时生成一个错误。

不需要单独铸造

// Using generics converts run time exceptions into
// compile time exception.
import java.util.*;

class Test
{
    public static void main(String[] args)
    {
        // Creating a an ArrayList with String specified
        ArrayList <String> al = new ArrayList<String> ();

        al.add("Success");
        al.add("Gideon");


        String s1 = (String)al.get(0);
        String s2 = (String)al.get(1);

    }
}

如果我们不使用泛型,那么,在上面的示例中,每次我们从ArrayList检索数据时,都必须将其键入类型。实际上,在每次检索操作中进行类型转换都会带来很大的压力。如果我们已经知道我们的列表只包含字符串数据,那么我们不需要每次都输入它。

// We don't need to typecast individual members of ArrayList
import java.util.*;

class Test
{
    public static void main(String[] args)
    {
        // Creating a an ArrayList with String specified
        ArrayList <String> al = new ArrayList<String> ();

        al.add("Success");
        al.add("Gideon");

        // Typecasting is not needed
        String s1 = al.get(0);
        String s2 = al.get(1);
    }
}

结语

泛型是Java语言的一个强大的补充,因为它使程序员的工作更容易,并且不太容易出错。泛型在编译时执行类型正确性,并且它支持实现泛型算法,而不会给我们的应用程序带来额外的开销。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容