Generics in Java, Java generics 的使用

【我的Android进阶之旅】修复错误:Use of generics not allowed for java type at 'com.fasterxml.jackson.databind’ 一、问题描述 刚把app项目的compileSdkVer 改为 28,buildToolsVer改为"28.0.3"之后,编译失败了,失败错误如下所示: Warning: Exception while processing task java.io.IOException: proguard.ParseException: Use of generics not allowed for jav... 阅读详情

Generics in Java, Java generics 的使用

1 Introduction to generics

Generics are a way to tell a compiler what type of object a collection can contain. The idea is to allow type (Integer, String, … etc and user defined types) to be a parameter to methods, classes and interfaces. For example, classes like HashSet, ArrayList, HashMap, etc use generics very well.

Advantages of Generics:

Programs that uses Generics has got many benefits over non-generic code.

  • Code Reuse 代码复用: We can write a method/class/interface once and use for any type we want.

  • Type Safety 类型安全 : Generics make errors to appear compile time than at run time (It’s always better to know problems in your code at compile time rather than making your code fail at run time). Suppose you want to create an ArrayList that store name of students and if by mistake programmer adds an integer object instead of string, compiler allows it. But, when we retrieve this data from ArrayList, it causes problems at runtime.

// A Simple Java program to demonstrate that NOT using 
// generics can cause run time exceptions 
import java.util.*; 
  
class Test 
{ 
    public static void main(String[] args) 
    { 
        // Creatinga an ArrayList without any type specified 
        ArrayList al = new ArrayList(); 
  
        al.add("Sachin"); 
        al.add("Rahul"); 
        al.add(10); // Compiler allows this 
  
        String s1 = (String)al.get(0); 
        String s2 = (String)al.get(1); 
  
        // Causes Runtime Exception 
        String s3 = (String)al.get(2); 
    } 
} 

// 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("Sachin"); 
        al.add("Rahul"); 
  
        // Now Compiler doesn't allow this 
        al.add(10);  
  
        String s1 = (String)al.get(0); 
        String s2 = (String)al.get(1); 
        String s3 = (String)al.get(2); 
    } 
} 
  • Individual Type Casting is not needed : If we do not use generics, then, in the above example every-time we retrieve data from ArrayList, we have to typecast it. (即String s1 = (String)al.get(0); ) Typecasting at every retrieval operation is a big headache. If we already know that our list only holds string data then we need not to typecast it every time.
// 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("Sachin"); 
		al.add("Rahul"); 

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

  • Implementing generic algorithms: By using generics, we can implement algorithms that work on different types of objects and at the same they are type safe too.

2 Generic methods in Java

Generic methods in Java are methods that allow you to create a new type parameter just for that method. This is useful if you are writing a method but want to be flexible about the type of objects you can pass in.

I have an array of characters called charArray. I also have an array of booleans called boolArray, and an array of integers called intArray. Then, I have created a method called arrayToList that iterates through all of the objects in an array and adds them to a list. I want to be able to pass any of these arrays into the method, even though they are of different types. So the first thing I have tried is making the arguments of the array to list method object types.

public class GenericMethods {

    static Character[] charArray = {'h', 'e', 'l', 'l', 'o'};
    static Integer[] intArray = {1, 2, 3, 4, 5};
    static Boolean[] boolArray = {true, false, true};

    public static List arrayToList(Object[] array, List<Object> list) {
        for (Object object : array) {
            list.add(object);
        }
        return list;
    }

    public static void main(String[] args) {
        List<Character> charList = arrayToList(charArray, new ArrayList<>());
        List<Boolean> boolList = arrayToList(boolArray, new ArrayList<>());
        List<Integer> intList = arrayToList(intArray, new ArrayList<>());
    }
}

Using objects means that I lose type safety. For example, in the main method, if I change the type of intList to string and compile this file, I don’t get any errors.

The solution is to make the array to list method a generic method The first thing I need to do is create a new type variable, which I will call T. This type variable only has local scope.

public class GenericMethods {

    static Character[] charArray = {'h', 'e', 'l', 'l', 'o'};
    static Integer[] intArray = {1, 2, 3, 4, 5};
    static Boolean[] boolArray = {true, false, true};

    public static <T> List<T> arrayToList(T[] array, List<T> list) {
        for (T object : array) {
            list.add(object);
        }
        return list;
    }

    public static void main(String[] args) {
        List<Character> charList = arrayToList(charArray, new ArrayList<>());
        List<Boolean> boolList = arrayToList(boolArray, new ArrayList<>());
        List<Integer> intList = arrayToList(intArray, new ArrayList<>());
        System.out.println(intList.get(0));
    }
}

Using this approach, I can keep the method flexible, but I can discover errors in the code much earlier on.

3 Using vargs in Java

Sometimes you might want to write a method that takes a variable number of arguments. In Java there is a feature called variable-length arguments, or varargs for short, which allows you to do this.

在写printShoppingList() method 的时候,不用让输入必须是列表,比如 printShoppingList(String[] items) , Instead,我们可以用三个点代替 [ ], 这样这个method接受多个variable输入,自动成为一个list.

public class Varargs {
    
    public static void main(String[] args) {
        String imem1 = "Apples";        
        String item2 = "Oranges";
        String item3 = "Pears";
        printShoppingList(imem1, item2, item3);
        printShoppingList("Bread", "Milk", "Eggs", "Bananas");
    }
    
    private static void printShoppingList(String... items) {
        System.out.println("SHOPPING LIST");
        for (int i = 0; i < items.length; i++) {
            System.out.println(i + 1 + ": " + items[i]);
        }
        System.out.println();

    }
}

Using a vararg method has made my code shorter and simpler, but it is still easy to read and understand.

4 The substitution principle in Java

he substitution principle, which is also known as the Liskov Substitution Principle, is an important concept in object-oriented programming because it allows you to write maintainable and reusable code.

It just means that if you have a variable of a given type you can assign it to a value that is a subtype of that type.

Because office is a subtype of building, I can pass it into this method. This is the substitution principle.

class Building {
    @Override
    public String toString() {
        return("building");
    }
}

class Office extends Building {        
   
    @Override
    public String toString() {
        return ("office");
    }
}

public class Main {
    
    
    public static void main(String[] args) {
        Building building = new Building();        
        Office office = new Office();
        build(building);
        build(office);
        
        List<Building> buildings = new ArrayList();
        buildings.add(new Building());
        buildings.add(new Office());
        printBuildings(buildings);
        
        List<Office> offices = new ArrayList();
        offices.add(new Office());
        offices.add(new Office());
        printBuildings(offices);
        
    }
    
    static void build(Building building) {
        System.out.println("Constructing a new " + building.toString());
    }
    
    static void printBuildings(List<Building> buildings) {
        for(int i = 0; i < buildings.size(); i++) {
            System.out.println(i + 1 + ": " + buildings.get(i).toString());
        }
    }
    
}

It is also important to know when the substitution principle does not apply. You might think that because office is a subtype of building that a list of type office is a subtype of a list of type building. However, this isn’t actually the case.

5 Using wildcards in generic programming

A wildcard is essentially an unknown type, and can give you more flexibility when writing methods.

To use a wildcard, I put a question mark and then write extends. (typing) Before the word building. This means that I can now pass in lists of any type that extends the building class.

Wildcards can also be used to specify that super types can be used when a subtype is specified. In this main class, I also have a method called addHouseToList, which takes a list of houses as an argument and adds a new house to it. Currently, I can only pass in a list of houses to this method. But if I wanted to be able to pass in a list of Buildings, I can use wildcards again. This time, I’ve put a question mark and the word super in front of house, where I specify the type of list. Now, I can pass in a list of buildings to this method.

class Building {
    public int numberOfRooms = 7;
    @Override
    public String toString() {
        return ("building");
    }

    public int getNumberOfRooms() {
        return numberOfRooms;
    }

    public void setNumberOfRooms(int numberOfRooms) {
        this.numberOfRooms = numberOfRooms;
    }
}
/*****************************************/
public class House extends Building {
 
    public int numberOfRooms = 10;
    @Override
    public String toString() {
        return ("house");
    }
            
    public int getNumberOfRooms() {
        return numberOfRooms;
    }
    
    public void setNumberOfRooms(int numberOfRooms) {
        this.numberOfRooms = numberOfRooms;
    }
}

class Office extends Building {        
    
    @Override
    public String toString() {
        return ("office");
    }
}

public class Main {
    
    
    public static void main(String[] args) {
        
        // List of buildings
        List<Building> buildings = new ArrayList();
        buildings.add(new Building());
        buildings.add(new Building());
        printBuildings(buildings);
        
        // List of offices
        List<Office> offices = new ArrayList();
        offices.add(new Office());
        offices.add(new Office());
        printBuildings(offices);

        // List of houses
        List<House> houses = new ArrayList();
        houses.add(new House());
        houses.add(new House());
        printBuildings(houses);
        
        addHouseToList(houses);
        addHouseToList(buildings);        
        
    }

    static void printBuildings(List<? extends Building> buildings) {
        for(int i = 0; i < buildings.size(); i++) {
            System.out.println(buildings.get(i).toString() + " " + (i + 1));
        }
        System.out.println();
    }
    
    static void addHouseToList(List<? super House> buildings) {
        buildings.add(new House());
        System.out.println();
    }
}

If you are unsure about when to use extends and when to use super with wildcards, you can think about invariables and outvariables. In the printBuildings method, I am passing in a list which provides data which I use inside the method, so this in an invariable. With invariables, it makes sense to use extends. In the addHouseToList method, I am using the method to give additional data by adding to the list. So this is an outvariable. And in this case it makes sense to use super.

Also note that it is generally a bad idea to use wildcards as return types for a method.

Mask2Former实战:用SwinTransformer+Deformable Attention搞定图像分割三大任务 本文实战解析了Mask2Former模型如何统一解决语义、实例和全景分割三大任务。通过集成Swin Transformer骨干网络与创新的Deformable Attention及Masked Attention机制,详细介绍了模型构建、训练策略及在COCO数据集上的性能表现,为开发者提供了高效的图像分割解决方案。 阅读详情

相关推荐

Android自动化新方案:ESP32-C3蓝牙HID模拟触控与手势操作实战(附源码)

本文详细介绍了使用ESP32-C3通过蓝牙HID协议实现Android设备自动化操作的完整方案。该硬件方案成本低廉且能完美规避系统风控,可模拟鼠标移动、点击及复杂手势操作,延迟低于50毫秒,适用于游戏连招和应用测试等场景。文章包含完整的源码实现和性能优化技巧。

kotlin6android的博客 377

java转json 报错处理机制

JSON-lib这个Java类包用于把bean,map和XML转换成JSON并能够把JSON转回成bean和DynaBean。   报错处理机制 commons-beanutils-1.8.0.jar不加这个包java.lang.NoClassDefFoundError: org/apache/commons/beanutils/DynaBean commons-collections....

sziitjiang的专栏 238

OpenFOAM收敛问题排查指南:从参数设置到网格优化

本文系统性地介绍了OpenFOAM计算中收敛问题的排查方法。从理解收敛本质出发,详细讲解了如何通过调优求解控制参数(如松弛因子、离散格式)、合理设置时间步长与耦合算法,以及优化网格质量来解决发散难题。文章提供了从软件设置到硬件网格的完整排查路径,帮助用户实现稳定高效的计算流体力学模拟。

fern8的博客 792

Java Generic 介绍 (pdf)

为什么80%的码农都做不了架构师?>>> ...

weixin_33750452的博客 179

如何导入su_利用GIS快速生成SU场地模型

01|前言:进入2021年了,希望大家也是一个新的开始。告诫自己多写文章多更新,多读点书多旅行。然而元旦由于出去玩了4天,积累了一些事情要处理,一直没有时间好好写点东西。今天给大家带来的分享主题叫“利用GIS快速生成SU场地模型”。相关的视频方法其实B站上也有,但我相信视频很多人都不会看,我自己也是。直接给大家上操作流程。主要的操作步骤是【获取场地的矢量shp文件】—【导入ArcScen...

weixin_33806859的博客 9813

【深度学习】通俗易懂讲解循环神经网络LSTM

目录 1、循环神经网络(Recurrent Neural Networks) 2、长依赖存在的问题 3、LSTM 网络 4、LSTMs的核心思想 5、一步一步理解LSTM 6、LSTM的变种 7、总结 1、循环神经网络(Recurrent Neural Networks) 人对一个问题的思考不会完全从头开始。比如你在阅读本片文章的时,你会根据之前理解过的信息来理解下面看到的文字。...

Nieson2012的专栏 2729

Generics in Java

The Java Generics programming is introduced in J2SE 5 to deal with type-safe objects. It makes the code stable by detecting the bugs at compile time. 一、Advantages of Generics: Code Reuse We can write ...

liu_rockefeller的博客 418

图像分割 - 使用Mask R-CNN模型在COCO数据集上进行图像分割任务

图像分割是计算机视觉领域的一个重要任务,它旨在将图像中的每个像素分类为对象或背景。Mask R-CNN是一种基于区域的卷积神经网络,可用于图像分割任务。它是Faster R-CNN的扩展,将目标检测与图像分割结合起来,能够同时检测和分割对象。在本博客中,我们将使用Mask R-CNN模型在COCO数据集上进行图像分割任务。我们将介绍如何下载和准备COCO数据集,以及如何使用Mask R-CNN模型进行训练和推理。

斌擎科技 1188

技术人成长之路

技术人成长之路 spring ConfigurableXxx.setXxx .addXxx XxxAware.setXxx 优秀的框架 JDK Spring Apache Commons guava Velocity Log4j 设计模式 Visitor 模式 vert.x 区块链

晨猫 453

架构师成长之路(1)--什么是架构师

前言: 哲学家常思考的问题:" 我是谁?"" 我从哪里来?"" 要到哪里去?不只是哲学家,我想每个人都有自己对这三个问题的认知。 如果我们要成为架构师,我们自己要面临的三大问题: 找准自己定位:我是谁?在哪里? 怎样做好架构师:我要做什么? 如何搭建架构师知识体系:我该怎么做? 这里面就是做事方法论:目标(我要做什么),方法(计划)(我该怎么做), 执行/行动找准自己定位:我是谁?在哪里...

黄规速博客:学如逆水行舟,不进则退 6万+

在WSL2中配置代理(Windows)

通过按照上述步骤在WSL2中配置代理,我们可以轻松地在Windows子系统Linux中使用代理服务器访问互联网。请确保提供正确的代理服务器地址和端口号,并根据实际情况进行修改。在WSL2中使用代理是一个常见的需求,它允许我们在Windows子系统Linux中通过代理服务器访问互联网。本文将详细介绍如何在WSL2中配置代理,并提供相应的源代码示例。如果返回的IP地址与代理服务器所在地不同,说明代理正常工作。希望本文能对你有所帮助!如有其他问题,请随时向我提问。替换为实际的代理服务器地址和端口号。

FcUnity的博客 4355

JAVA中的泛型Generics in Java

泛型的概念:Java泛型是一种参数化类型的机制,允许我们在编写代码时指定类型的参数,以增加代码的灵活性和可重用性。泛型类和泛型方法:我们可以创建泛型类和泛型方法,使其能够适用于不同类型的数据。类型参数和类型实参:泛型类和泛型方法中的类型参数表示未知的类型,而类型实参则是在使用泛型时传递的具体类型。通配符:通配符是一种特殊的语法,用于表示未知类型或不确定类型的参数。通配符使用?表示,可以用在泛型类、泛型方法和泛型接口中。无界通配符:使用?表示,表示可以匹配任何类型。有界通配符:使用?

qq_52695936的博客 197

DBeaver配置本地mysql-connector驱动文件

本文摘要:介绍了数据库驱动管理的基本操作步骤:1)新建驱动管理器,填写MySQL驱动名称、类名和类型;2)添加本地MySQL驱动文件;3)创建数据库连接并测试。适用于MySQL5.x和8.x版本,帮助用户快速配置数据库连接。

litlit023的专栏 1686

Thinking in java-38 Java 泛型Generics in java

1. Generics 泛型引入泛型是在Java 5 之后引入到java 语言中的,其目的是为了提供编译时类型检查,减少ClassCastException异常风险。容器参数化能力是当初Generic引入的一个主要动力,它将运行时异常ClassCastException在编译时就强制检查,如果类型不匹配将抛出一个编译时错误。2. Generic Class泛型类我们可以定义泛型类。泛型类型是一种具

toseektruth的博客 453

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

008 The Generics In JAVA

泛型是JAVA的核心特型之一,我们先看一个例子: 没有使用泛型前,如下: import java.util.ArrayList; import java.util.List; public class GenericsStu { public static void main(String[] args) { List list = new...

183

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Generics and Wildcards in Java

这里写代码片 import java.util.ArrayList;class Machine {@Override public String toString() { return "I am a Machine"; }public String start() { return "the machine starting"; } }class Camera extends M

若砚的博客 437

Generics in the Java Programming Language Java

Generics in the Java Programming LanguageJava编程语言中的泛型Gilad BrachaJuly 5, 2004Contents内容1 Introduction 介绍22 Defining Simple Generics定义简单泛型 33 Generics and Subtyping 泛型和子类型44 Wildcards 通

dracularking的竹林小屋 3160

Thinking in java——Generics

​Ordinary classes and methods work with specific types:either primitives or class types. If you are writing code that might be used across more types, this rigidity can be overconstraining.     O...

hnggg 586

Generics in C#

IntroductionSome New features have been added to C# language with version 2.0 of .NET. which are: Generics Iterators Anonymous methods Partial classes In this Article I will explain abou

流男@水孩 1068

thinking in java——Generics

Ordinary classes and methods work with specific types:either primitives or class types. If you are writing code that might be used across more types, this rigidity can be  overconstraining.

poijm 758

《Generics in the Java Programming Language》译文

泛型 java

路漫漫,等风来 1109

Java Development - Generics

Java 泛型是 JDK 5 中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的数据类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,然后在使用时再指定此参数具体的值,这样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

qq_34377273的博客 946

Generics(Thinking in Java)

Generic Methods1publicclassGenericMethods{2public<T>voidf(Tx)3{4System.out.println(x.getClass().getName());5}67publicstaticvoidmain(String[]a...

weixin_30938149的博客 190

java generics implicit cast_Why are implicit generics in classes not allowed in Java? [on hold]

I am trying to understand why Java does not allow using implicit types in generic classes as it does in generic methods.I have scoured the webs for answers on this, but have yet to come across a reaso...

weixin_42500279的博客 97
上一篇: Leetcode 38. Count and Say Java解法
下一篇: Java Map/Collections 的使用场景
YuanTheCoder
博客等级 码龄9年 2粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值