精华内容
下载资源
问答
  • java泛型数组的误区

    2020-09-15 11:37:53
    java泛型数组的误区结论Java泛型描述:原因分析:底层原理:解决方案: 结论 不能(直接)创建泛型数组,但可以参数化数组本身的类型(即是将数组应该存储的对象进行参数化)。 泛型数组实际的运行时对象数组只能是...


    结论

    1. 不能(直接)创建泛型数组,但可以参数化数组本身的类型(即是将数组应该存储的对象进行参数化)。
    2. 泛型数组实际的运行时对象数组只能是原始类型

    # 项目场景:

    实例化泛型数组时,编译器直接报错
    在这里插入图片描述


    Java泛型描述:

    首先理解Java泛型的定义:泛型,即“参数化类型”,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

    例如:List中,String是类型实参,也就是说,相应的List接口中肯定含有类型形参。List接口中采用泛型化定义之后,< E >中的E表示类型形参,可以接收具体的类型实参,并且此接口定义中,凡是出现E的地方均表示相同的接受自外部的类型实参

    泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。


    原因分析:

    底层原理:

    由于泛型具有擦除机制,在运行时的类型参数会被擦除,Java只知道存储的对象是一个Object而已,而对于Java的数组来说,他必须知道它持有的所有对象的具体类型,而泛型的这种运行时擦除机制违反了数组安全检查的原则。

    由于擦除,运行期的数组类型只能是 Object[]


    解决方案:

    所以不能实例化java泛型数组,其本身就和泛型机制冲突。


    可以这样理解,

    在这里插入图片描述

    arr数组中存的是String,而s数组中存的是List,List本身就是数组,数组不能存数组。


    https://www.cnblogs.com/MrJR/p/10463479.html
    https://www.cnblogs.com/ixenos/p/5648519.html
    https://www.cnblogs.com/lwbqqyumidi/p/3837629.html

    展开全文
  • java泛型数组

    2019-10-02 08:24:00
    java不支持泛型数组,即T[]t。相关功能通过list来实现。 这里主要谈一下为什么不支持。 java为了兼容1.5以上版本,同时尽可能少的改动jvm,因此基于编译器实现泛型,运行时进行了类型擦除。 使用list<T>时...

    java不支持泛型数组,即T[]t。相关功能通过list来实现。

    这里主要谈一下为什么不支持。

    java为了兼容1.5以上版本,同时尽可能少的改动jvm,因此基于编译器实现泛型,运行时进行了类型擦除。

    使用list<T>时,编译器会检查add方法的参数类型,不符合的话会报错。

    但是对数组元素赋值时,不会检查类型,因此若使用不当,会出现运行时的类型转换异常,因此java,不支持T[]t形式的泛型数组。

    转载于:https://www.cnblogs.com/swaggyC/p/5976145.html

    展开全文
  • 一、说明Java 提供一个类可以解决数组的动态长度的问题,它就是 ArrayList 类,即泛型数组列表,也就是所谓的动态数组。使用 ArrayList 可以实时地添加元素而不用去管长度的问题。ArrayList 属于集合类库,实现了 ...

    一、说明

    Java 提供一个类可以解决数组的动态长度的问题,它就是 ArrayList 类,即泛型数组列表,也就是所谓的动态数组。使用 ArrayList 可以实时地添加元素而不用去管长度的问题。

    ArrayList 属于集合类库,实现了 List 接口。

    二、基本使用

    1.声明

    ArrayList 是一个采用 类型参数 的 泛型类。需要用尖括号将类名括起来加在后面,以指定数组列表保存的元素对象类型。注意尖括号内只能是类,不能是基本数据类型,如要存储基本数据类型,可使用对象包装器(Integer 等)

    ArrayList arrList = new ArrayList(); //声明和构造一个用来保存 String 类型的动态数组

    2.元素的添加与移除

    使用 add 方法将元素添加到数组列表中,分为默认的末尾添加和指定顺序添加。使用索引添加时,索引后面的元素都会往后移一位。

    arrList.add("first");//添加到末尾

    arrList.add(3,"third");// 通过索引添加到第三位,原本在第三位及后面的元素顺次后移

    使用 remove 方法删除指定位置元素,其后的元素将顺次前移,删除的元素将通过返回值返回。

    String s = arrList.remove (3);//删除第三个元素,s = third

    对数组实施插入和删除操作的效率很低。

    3.获取数组长度

    使用 size 方法获取数组列表的实际元素长度 ,相当于数组的 length 方法。

    4.访问数组列表元素

    ArrayList 的元素只能通过 set(替换元素) 和 get(获取元素) 方法访问。注意,使用 set 方法设置元素时,只能替换已经存在的元素。

    5.将 ArrayList 转换为数组

    使用 toArray 方法将 ArrayList 转换为数组。

    String [] arr = new String[arrList.size()];

    arrList.toArray(arr);

    三、扩展使用

    1.长度问题

    如果能够预估数组的元素数量,可以预先设置数组大小,先分配固定空间。有两种方法预设,分别是构造时传入参数和 ensureCapacity 方法。

    ArrayList aList = new ArrayList<>(100);

    ArrayList bList = new ArrayList<>();

    bList.ensureCapacity(100);//要在数组使用前调用

    两种方法均为数组分配100个对象的空间。

    ArrayList 的初始分配空间和数组不同,ArrayList只是预留空间,其内没有元素。

    如果添加时元素超过100个,会再次分配100个空间。这意味着如果有102个数,ArrayList的实际占用空间是200个对象的空间。

    在长度确定之后,可以使用 trimToSize 方法将容量削减到当前尺寸。但再次添加时又会增加100个空间。

    2.ArrayList 还有一些不常用的方法,如 isEmpty 判断是否为空、addAll 添加集合等,使用时参考官方文档。

    展开全文
  • 虽然 Java 中允许在运行时确定数组的大小。int size = ...;String[] staff = new String[size];但是并没有完全解决运行时动态更改数组的问题。一旦确定了数组的大小,就不能很容易地改变它。在 Java 中,解决这个...

    虽然 Java 中允许在运行时确定数组的大小。

    int size = ...;

    String[] staff = new String[size];

    但是并没有完全解决运行时动态更改数组的问题。

    一旦确定了数组的大小,就不能很容易地改变它。在 Java 中,解决这个问题最简单的方法是使用 Java 中另外一个类,名为 ArrayList。ArrayList 类类似于数组,但在添加或删除元素时,它能够自动地调整数组容量,而不要为此编写任何代码。

    ArrayList 是一个有类型参数(type parameter) 的泛型类(generic class)。为了指定数组列表保存的元素对象的类型,需要用一对尖括号将类名括起来追加到 ArrayList 后面,例如 ArrayList<String>。

    1. 声明数组列表

    声明和构造一个保存 String 对象的数组列表:

    ArrayList<String> list = new ArrayList<String>();

    在 Java 10 中,最好使用 var 关键字以避免重复写类名:

    var list = new ArrayList<String>();

    如果没有使用 var 关键字,可以省略右边的类型参数:

    ArrayList<String> list = new ArrayList<>();

    这称为 “菱形” 语法,因为空尖括号 <> 就像是一个菱形。可以结合 new 操作符使用菱形语法。编译器会检查新值要什么。如果赋值给一个变量,或传递到某个方法,或者从某个方法返回,编译器会检査这个变量、参数或方法的泛型类型,然后将这个类型放在 <> 中。在这个例子中,new ArrayList<>() 将赋至一个类型为 ArrayList<String> 的变量,所以泛型类型为 String

    警告: 如果使用 var 声明 ArrayList,就不能使用菱形语法。以下声明:

    var list = new ArrayList<>();

    会生成一个 ArrayList<Object>。

    注释: Java 5 以前的版本没有提供泛型类,而是有一个保存 Object 类型元素的 ArrayList 类,它是一个“自适应大小”(one-size-fits-all)的集合。仍然可以使用没有后缀 <...> 的 ArrayList,这将被认为是删去了类型参数的一个“原始”类型。

    注释: 在 Java 的老版本中,程序员使用 Vector 类实现动态数组。不过,ArrayList 类更加高效,没有任何理由再使用 Vector 类。

    使用 add 方法可以将元素添加到数组列表中。例如,下面展示了如何将 String 对象添加到一个数组列表中:

    ArrayList staff = new ArrayList();

    staff.add(new String("Harry Hacker"));

    staff.add(new String("Tommy Tester"));

    数组列表管理着一个内部的对象引用数组。最终,数组的全部空间有可能被用尽。这时就显现出数组列表的魅力了:如果调用 add 且内部数组已经满了,数组列表就会自动地创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中。

    如果已经清楚或能够估计出数组可能存储的元素数量,就可以在填充数组之前调用 ensureCapacity 方法:

    list.ensuteCapacity(100);

    这个方法调用将分配一个包含 100 个对象的内部数组。这样一来,前 100 次 add 调用不会带来开销很大的重新分配空间。

    还可以把初始容量传递给 ArrayList 构造器:

    ArrayList<String> list = new ArrayList<>(100);

    警告: 如下分配数组列表:

    new ArrayList<>(100) // capacity is 100

    这与分配一个新数字有所不同:

    new String[100] // size is 100

    数组列表的容量与数组的大小有一个非常重要的区别。如果分配一个有 100 个元素的数组。数组就有 100 个空位置(槽)可以使用。而容量为 100 个元素的数组列表只是可能保存 100 个元素(实际上也可以超过 100,不过要以重新分配空间为代价),但是在最初,甚至完成初始化构造之后,数组列表不包含任何元素。

    size 方法将返回数组列表中包含的实际元素个数。

    list.size()

    将返回 staff 数组列表的当前元素个数,它等价于数组 a 的 a.length。

    一旦能够确认数组列表的大小将保持恒定,不再发生变化,就可以调用 trimToSize 方法。这个方法将存储块的大小调整为保存当前元素数量所需要的存储空间。垃圾回收器将回收多余的存储空间。

    一旦消减了数组列表的大小,添加新元素就需要花时间再次移动存储块,所以应该在确认不会再向数组列表添加任何元素时再调用 trimToSize。

    java.util.ArrayList<E> 1.2

    ArrayList<E>

    构造一个空数组列表。

    boolean add(E obj)

    在数组列表的末尾追加一个元素。永远返回 true。

    int size()

    返回当前存储在数组列表中元素个数。(当然,这个值永远不会大于数组列表的容量)

    void ensureCapacity()

    确保数组列表不重新分配内部存储数组的情况下有足够的容量存储给定数量的元素。

    void trimToSize()

    将数组列表的存储容量削减到当前大小。

    2. 访问数组列表元素

    数组列表自动扩展容量的便利增加了访问元素语法的复杂程度。其原因是 ArrayList 类并不是 Java 程序设计语言的一部分;它只是由某个人编写并在标准库中提供的一个实用工具类。

    数组列表使用 get 和 set 方法访问或改变数组列表的元素。

    警告: 只有当前数组列表的大小大于 i 时,才能够调用 list.set(i, x)。例如这段代码时错误的:

    var list = new ArrayList<String>(100); // capacity 100, size 0

    list.set(0, x);

    要使用 add 方法为数组添加新元素,而不是 set 方法,set 方法只是用来替换数组列表中已经加入的元素。

    要得到一个数组列表的元素,使用 get 方法:

    String srt = list.get(i);

    注释: 没有泛型时,原始的 ArrayList 类提供的 get 方法别无选择,只能返回 Object,因此,get 方法的调用者必须对返回值进行强制类型转换:

    String str = (String) list.get(i);

    原始的 ArrayList 还存在一定的危险性。它的 add 和 set 方法接受任意类型的对象。对于下面这个调用:

    list.set(i, new Date());

    它能正常编译而不会给出任何警告,只有在检索对象并试图对它进行强制类型转换时,才会发现有问题。如果使用 ArrayList<String>,编译器就会检测到这个错误。

    这个技巧可以一举两得,即可以灵活地扩展数组,又可以方便地访问数组列表。首先,创建一个数组列表,并添加所有的元素。

    var list = new ArrayList();

    while (...) {

    x = ...;

    list.add(x);

    }

    执行完上述操作后,使用 toArray 方法将数组元素拷贝到一个数组中。

    var a = new X[list.size()];

    list.toArray(a);

    有时需要在数组列表的中间插入元素,为此可以使用 add 方法并提供一个索引参数。

    var str = "";

    int n = staff.size() / 2;

    list.add(n, str);

    位置 n 及以后的元素都要向后移动一个位置,为新元素留出空间。插入新元素后,如果数组列表新的大小超过了容量,数组列表就会重新分配它的存储数组。

    可以从数组列表中间删除一个元素:

    String srt = list.remove(n);

    位于这个位置之后的所有元素都向前移动一位,并且数组的大小减 1。

    插入和删除元素的操作效率很低。对于较小的数组列表来说,不必担心这个问题。但如果存储的元素比较多,又经常需要在中间插入、删除元素,就应该考虑使用链表了。

    可以使用 “for each” 循环遍历数组列表的内容:

    for (String str : list) {

    do something with str

    }

    这个循环和下列代码具有相同的效果:

    for (int i = 0; i < list.size(); i++) {

    String str = list.get(i);

    do something with str

    }

    使用数组列表情注意下面的变化:

    不必指定数组列表的大小。

    使用 add 将任意多的元素添加到数组列表中。

    使用 size() 而不是 length 统计元素个数。

    使用 list.get(i) 而不是 list[i] 来访问元素。

    java.util.ArrayList<E> 1.2

    E set(int index, E obj)

    将值 obj 放置在数组列表的指定索引位置,返回之前的内容。

    E get(i)

    得到指定索引位置存储的值。

    void add(int index, E obj)

    后移元素从而将 obj 插入到指定索引位置。

    E remove(int index)

    删除指定索引位置的元素,并将后面的所有元素前移。返回所删除的元素。

    3. 类型化与原始数组列表的兼容性

    假设有下面这个遗留下来的类:

    public class EmployeeDB

    {

    public void update(ArrayList list) { . . . }

    public ArrayList find(String query) { . . . }

    }

    public class Employee {

    private String name;

    private double salary;

    private LocalDate hireDay;

    public Employee(String name, double salary, int year, int month, int day) {

    this.name = name;

    this.salary = salary;

    hireDay = LocalDate.of(year, month, day);

    }

    }

    可以将一个类型化的数组列表传递给 update 方法,而并不需要进行任何类型转换。

    EmployeeDB employeeDB = new employeeDB();

    ArrayList list = . . .;

    employeeDB.update(list);

    可以将 list 对象传递给 update方法。

    相反地,将一个原始 ArrayList 赋给一个类型化 ArrayList 会得到一个警告。

    ArrayList<String> result = employeeDB.find(query); // yields warning

    注释: 为了能够看到警告的文字信息,要将编译选项置为 -Xlint:unchecked。

    使用强制类型转换并不能避免出现警告。

    ArrayList<String> result = (ArrayList<Employee>) employeeDB.find(query);

    // yields another warning

    这样将会得到另外一个警告信息,指出类型转换有误。

    警告: 尽管编译器没有给出任何错误信息或警告,但是这样调用并不太安全。在 update 方法中,添加到数组列表中的元素可能不是 Employee 类型。访问这些元素时就会出现异常。 听起来似乎很吓人,但思考一下就会发现,这种行为与 Java 中引入泛型之前是一样的,虚拟机的完整性并没有受到威胁。在这种情形下,既没有降低安全性,也没有受益于编译时的检查。

    这就是 Java 中不尽如人意的泛型类型限制所带来的结果。出于兼容性的考虑,编译器检查到没有发现违反规则的现象之后,就将所有的类型化参数列表转换成原始 ArrayList 对象。在程序运行时,所有的数组列表都是一样的,即虚拟机中没有类型参数。因此,强制类型转换(ArrayList)和(ArrayList<Employee>)将执行相同的运行时检查。

    在这种情形下,你并不能做什么。在与遗留的代码交互时,要研究编译器的警告,确保这些警告不太严重就行了。

    一旦确保问题不太严重,可以用 @SuppressWamings("unchecked") 注解来标记接受强制类型转换的变量,如下所示:

    @SuppressWarnings("unchecked") ArrayList result =

    (ArrayList) employeeDB.find(query); // yields another warning

    展开全文
  • 一、泛型概念泛型是JavaSE1.5的新特效,泛型的本职是参数化类型,就是说所操作的数据类型被指定为一个参数,这种参数可以用在类、接口和方法中创建,分别称为泛型类、泛型接口、泛型方法。引用泛型的好处是安全简单...
  • 泛型泛型java 1.5中定义的一种新的数据类型,是一种参数化的类,也叫“类中类”,它是面向对象的扩展。通过泛型可以定义类型安全的数据类型,它的最显著应用就是创建集合类,可以约束集合类内的元...
  • 泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码:class Foo{//private T t =new T();//报错Cannot instantiate the type T//private T[] tArray= new T[5];//报错Cannot create a ...
  • java泛型数组列表-ArrayList类

    千次阅读 2016-12-05 11:44:11
    泛型数组列表-ArrayList类 在java中,数组的大小是不能改变的,为解决这一问题可使用ArrayList类,它在添加或删除元素时,具有自动调节数组容量的功能,而不需要为此编写任何代码。ArrayList是一个采用类型参数的...
  • Java泛型数组列表

    2012-09-03 20:27:28
    泛型数组列表 在Java中我们定义了一个数组就要确定数组的大小,而一担确定了数组的大小之后想改变数组大小就很麻烦了,所以Java为我们提供了ArrayList类,这是一个采用类型参数的泛型类。为了指定数组存储对象的类型...
  • java创建泛型数组

    2020-01-15 19:34:06
    java中创建泛型数组并不是不可能,创建泛型数组通过反射,给构造函数传递两个参数,一个类型标记,一个数组大小。‘ 简单Demo如下: import java.lang.reflect.Array; /** * 创建泛型数组 * @author hetia...
  • java 泛型数组 深度解析

    千次阅读 2013-01-30 12:02:55
    泛型数组 只能作为参数类型 或者 函数参数Java中,Object[]数组可以是任何数组的父类,或者说,任何一个数组都可以向上转型成父类的数组,这个时候如果我们往里面放不同于原始数据类型 但是满足后来使用的...
  • 希望通过java反射以及泛型来实现动态测试SortClass中的各种排序函数,这时getmethod方法和invoke方法的参数不知道如何解决了。我写的这个实现一直报参数异常代码class SortClass{//选择排序public void selectSo...
  • ------------- android培训、java培训、期待与您交流! ------------- 关于数组与泛型: Thrinking Java这样提到,数组与泛型...一般解决方案:在任何想要创建泛型数组的地方都使用ArrayList. 成功创建数组的方式
  • 虽然 Java 中允许在运行时确定数组的大小。  int size = ...;  String[] staff = new String[size]; 但是并没有完全解决运行时动态更改数组的问题。 一旦确定了数组的大小,就不能很容易地改变它。在 Java 中,...
  • ArrayList介绍 普通的数组一旦确定大小,想要再改变空间大小就不太容易了。 在Java中,解决这个问题最简单的方式是使用Java的ArrayList类。 下面声明和构造一个保存...在Java SE7中,可以省去右边的类型参数:但...
  • 我有一个ClassClass ClassO....调用的例程中,其中O是通用类参数.我找不到如何执行此操作.我特别需要O [](而不是ArrayList O或类似的东西),因为我需要经常在循环体内获取它的元素,这对我算法的执行时间很重要....
  • 1.ArrayList是一个采用类型参数泛型类。2.为了指定数组列表保存的元素对象类型,需要用一对尖括号将类名括起来加在后面。ArryList s = new ArrayList();//右边尖括号里的参数可以省略3.使用add方法将元素添加到...
  • 泛型数组

    2021-04-11 13:54:39
    定义泛型数组 在写程序时,大家可能会遇到类似String[] list = new String[8];的需求,这里可以定义String数组,当然我们也可以定义泛型数组泛型数组的定义方法为 T[],与String[]是一致的,下面看看用法: ...
  • 目录何为泛型擦除泛型数组?另辟蹊径 何为泛型擦除 java中实现的泛型是伪泛型:即对于泛型graph<Integer>和graph<Double>,在编译后都会变成graph,在JVM看来没有区别。 Java中的泛型基本上都是在编译器...
  • JDK1.5 令我们期待很久,可是当...1、Java泛型  其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型
  • 5.3泛型数组列表 package arrayList; import inheritance.Employee; //此处导入的为同一项目下 inheritance包中的 employee类 import java.util.ArrayList; public class ArrayListT { public static void main...
  • 简介上一篇文章介绍了泛型的基本用法以及类型擦除的问题,现在来看看泛型和数组的关系。数组相比于Java 类库中的容器类是比较特殊的,主要体现在三个方面:数组创建后大小便固定,但效率更... 能否创建泛型数组呢?...
  • 我有一个包含T和一些元数据的数组(或列表)的接口 .interface DataWithMetadata {val someMetadata: Intfun getData(): Array}如果我编写最简单的接口实现,我会在 emptyArray() 上收到编译错误:"Cannot use T as a ...
  • Java“禁止”泛型数组

    2019-01-07 09:45:00
    Java“禁止”泛型数组 原文:https://blog.csdn.net/yi_Afly/article/details/52058708 1. 泛型定义泛型编程是一种通过参数化的方式将数据处理与数据类型解耦的技术,通过对数据类型施加约束(比如Java中的有界...
  • JDK1.5 令我们期待很久,可是当他发布的...1、Java泛型 其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可...
  • 学过Java泛型的人都知道,Java泛型是不止直接使用new实例化参数化类型的数组 比如我们定义一个泛型化的LinkedStack的栈类 package chapter5.genericity; public class LinkedStack<T> { private static ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 978
精华内容 391
关键字:

java泛型数组参数

java 订阅