精华内容
下载资源
问答
  • java数组元素类型为基本数据类型和引用类型有什么不同? 对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内存空间,然后直接将数组元素的值存入对应数组元素中...

    java数组元素类型为基本数据类型和引用类型有什么不同?

    对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内存空间,然后直接将数组元素的值存入对应数组元素中。
    如:

    int[] a1={1,2,3,4,5};
    

    引用类型数组的数组元素是引用,因此情况变得更加复杂:每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效数据。
    如:

    MyClass[] mc=new MyClass[10];
    
    展开全文
  • Java数组之数组的类型

    2016-03-15 22:14:08
    Java数组之数组的类型在Java中,数组也是引用类型,在创建时被分配到堆内存上。数组是特殊的类,但Java中并没有定义它的类路径。若仿照通常定义数组的语法,我们来加载数组:Class.forName("java.lang.String[]");...

    在Java中,数组也是引用类型,在创建时被分配到堆内存上。数组是特殊的类,但Java中并没有定义它的类路径。若仿照通常定义数组的语法,我们来加载数组:

    Class.forName("java.lang.String[]");

    尝试运行,程序会抛出异常 ClassNotFoundException。究其原因是,数组虽然是一个类,在声明时用 String[] 定义,但编译后会映射为其他表达,不同类型的数组编译前后的对应如下表:

    数组声明时编译后类型
    byte[][B
    char[][C
    double[][D
    float[][F
    int[][I
    long[][J
    short[][S
    boolean[][Z
    引用类型[L引用类型

    对于最后一条,以 String 为例而言, String[] 编译后成为 “[Ljava.lang.String;”。为了验证,在这里我声明了几个数组进行测试,相应输出如截图。

    public class TestArrClass{
        public static void main(String[] args){
            int[] intArr = {1};
            long[] longArr = {1L};
            double[] douArr = {0.0};
            Integer[] intArr2 = {1};
            String[] strArr = {"1"};
            TestArrClass[] testArrClass = {new TestArrClass()};
    
            System.out.println("int[]:" + intArr.getClass());
            System.out.println("long[]:" + longArr.getClass());
            System.out.println("double[]:" + douArr.getClass());
            System.out.println("Integer[]:" + intArr2.getClass());
            System.out.println("String[]:" + strArr.getClass());
            System.out.println("TestArrClass[]:" + testArrClass.getClass());
        }
    }

    程序输出

    注意: Integer[] 编译后符合表中最后一条,即 引用类型,因为Integer是继承自Object的类,虽然有自动拆箱装箱,但本质依然是正常的类。
    看到这里,我相信大家在调式代码时看到类似

    java.lang.Integer cannot be cast to [Ljava.lang.Object;
    [Ljava.lang.Object; cannot be cast to YourClass

    的异常报错时,也必定知道是什么意思,知道如何下手修改了!


    更多数组相关请参考:
    Java数组101
    Java编程思想
    编写高质量代码:改善Java程序的151个建议

    展开全文
  • Java数组 强制类型转换

    千次阅读 2020-07-15 20:18:30
    数组的强制类型转换数组的强制类型转换数组类型转换的问题为什么会出现在我脑海中? 数组的强制类型转换 最重要的是!!!最开始的时候声明的数组类型!!! 最重要的是!!!最开始的时候声明的数组类型!!! 最...

    数组的强制类型转换

    最重要的是!!!最开始的时候声明的数组类型!!!
    最重要的是!!!最开始的时候声明的数组类型!!!
    最重要的是!!!最开始的时候声明的数组类型!!!

    例如:

    Object[] objects = new Object[2];
    Object[0] = "hello";
    Object[1] = "world";
    Object[] objects1 = {"kkkk", 3434}
    
    System.out.println(objects.getClass());
    System.out.println(objects1.getClass());
    System.out.println(objects[0].getClass());
    System.out.println(objects[1].getClass());
    System.out.println(objects1[0].getClass());
    System.out.println(objects1[1].getClass());
    

    class [Ljava.lang.Object;
    class [Ljava.lang.Object;
    class java.lang.String
    class java.lang.String
    class java.lang.String
    class java.lang.Integer
      根据实验,一开始就声明为String数组,可以在需要时自动转为Object数组,之后可以通过强制类型转换再转回String数组
      但是,如果一开始就声明为Object数组,那么,即便这个数组中存放的全部是String对象,也是不能转换为String数组的!!!

    数组类型转换的问题为什么会出现在我脑海中?

    先上代码:

    public class Base {
        public ArrayList<String> data;
        
        public String[] getData() {
            return (String[])data.toArray();
        }
        
        public void setData(String[] data) {
            this.data = new ArrayList<String>(Arrays.asList(data));
        }
    }
    

      遇到的问题如下:当调用setData设置好data之后,紧接着getData()将会抛出一个类型转换异常java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;提示不能将String数组强转为Object数组,这是为什么呢???明明我是String泛型的ArrayList呀,怎么一toArray()就成了Object数组了呢???而且这个Object数组为什么不能强转成String数组呢?我自己用String数组转换成Object数组之后,是可以转回String数组的呀,为什么这里就转不回去,而且报错了呢??????

      带着问题的 我 和 源码 展开了“深入”交流
      参照源代码的时候发现,首先,Arrays.asList(data)依然返回的是泛型,也就应该是String[]。因此,上述ArrayList的那个构造方法,传入参数时,应该是String[]。

      这就神奇了,既然我参数传入的时候还是String数组,为什么data.toArray();就成了Object数组了呢???难道是data.toArray()这个方法在搞鬼??
      带着疑问,继续阅读源码,发现这个无参的toArray()方法转向了Arrays类的静态方法Arrays.copyOf(elementData, size);,之后又转向了copyOf的三参数重载方法:

    class ArrayList {
    	... ...
    	public Object[] toArray() {
        	return Arrays.copyOf(elementData, size);
    	}
    }
    
    class Arrays {
    	... ...
    	public static <T> T[] copyOf(T[] original, int newLength) {
            	return (T[]) copyOf(original, newLength, original.getClass());
    	}
    	
    	... ...
        public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
            @SuppressWarnings("unchecked")
            T[] copy = ((Object)newType == (Object)Object[].class)
                ? (T[]) new Object[newLength]
                : (T[]) Array.newInstance(newType.getComponentType(), newLength);
            System.arraycopy(original, 0, copy, 0,
                             Math.min(original.length, newLength));
            return copy;
        }
    }
    

      那么问题来了,这个作为参数传入的ArrayList的实例域elementData实际上是什么类型的数组呢?这个3个参数的copyOf又干了什么呢???
      首先,看看这个三参数copyOf()函数干了什么:我们不妨假设elementData.getClass()依然是String数组。如果这样的话,应该会调用?:表达式的第二个代码:

    			: (T[]) Array.newInstance(newType.getComponentType(), newLength);
    

      Array.newInstance()返回的是Object引用类型,并最终导向native代码。虽然我不清楚它做了什么,但是有两点可以确定:

    1. 源代码既然在强转的时候没有报错,说明该方法的返回的实际对象一定是T子类的数组。而T类型是什么呢?因为假设传入的是String数组的Class对象,且这里String除了Object之外没有超类了,所以T必为Object类型;
    2. 很显然冒号左侧才是新建了一个Object数组,那冒号右面猜测应该是建立了一个泛型数组,但是暂时不确定。
    3. 在返回到二参数copyOf()方法中的时候,这里的T数组我们已经假设为String数组(因为我们假设elementData是String数组),在将Array.newInstance()产生的数组强转为T数组(String数组)时没有报错,说明,Array.newInstance()产生的必然是String数组。

      也就是说,在二参数copyOf()返回时,返回类型必然和elementData是同一类型,那我们又假设elementData是String数组,最后toArray()返回就不是String数组吗???怎么之后强转会出错呢?

      那只能说明假设错了!!!!!

      那说明elementData已经不是String类型了!那是什么时候变的呢?我们来到了它的构造方法:

    class ArrayList {
    	......
    	public ArrayList(Collection<? extends E> c) {
            elementData = c.toArray();
            if ((size = elementData.length) != 0) {
                // c.toArray might (incorrectly) not return Object[] (see 6260652)
                if (elementData.getClass() != Object[].class)
                    elementData = Arrays.copyOf(elementData, size, Object[].class);
            } else {
                // replace with empty array.
                this.elementData = EMPTY_ELEMENTDATA;
            }
        }
    }
    

      看到这个方法的第4、5行,已经当场气死~原来在构造方法的时候,就已经将不是Object数组的数组转成了Object数组,并存放在elementData中,而无参的toArray()方法并没有对其特殊处理,直接返回了一个Object数组(虽然里面元素仍然是String)。

      所以,如果要返回泛型数组,该怎么办呢?
      答案是:调用带参的toArray()方法!!

    展开全文
  • Java数组类型

    千次阅读 2016-06-17 17:52:01
    Java中,数组可以说是经常用到的,但关于数组是什么类型的这个问题,我却没有深入研究过。以下内容参考自《Java语言规范》,记录了数组类型是什么?更进一步地说,数组对象的getClass()返回的是什么?1.数组更...

    在Java中,数组可以说是经常用到的,但关于数组是什么类型的这个问题,我却没有深入研究过。以下内容参考自《Java语言规范》,记录了数组的类型是什么?更进一步地说,数组对象的getClass()返回的是什么?

    1.数组更详细的特点

    数组具有以下几点特点:

    a.在Java编程语言中,数组是动态创建的对象,可以被赋值给Object类型的变量。Object类的所有方法都可以在数组上调用。

    b.数组对象包含大量的变量。

    c.数组的所有元素都具有相同的类型,称为数组的元素类型。如果数组的元素类型为T,那么数组自身的类型就写作T[ ]。

    这里针对数组的特点a进行详细说明:
    下面代码片段中,会创建一个数组对象,并且这个对象可以赋值给Object对象。

    int[] ai1 = {1,2};//隐式地创建一个新的数组对象
    int[] ai = new int[2];//显式地创建一个数组对象
    Object o = ai;//数组对象可以赋值给Object类型的变量
    o = ai1;

    通过上面的代码片段,再联系“数组是动态创建的对象”这句话,我们可以猜测:数组的类型很可能是运行时通过反射动态创建的,并且其类型是Object的子类。

    既然知道数组具有特定类型了,那么这个类型具有什么成员呢?下面将进行说明。

    2.数组类型的成员

    数组类型的成员包括以下所有内容:

    • public final 域 length,它包含了数组的元素数量。length可以是正数或0。
    • public 方法 clone,它覆盖了Object类中的同名的方法,并且不会抛出任何受检异常。
      多维数组的克隆是浅复制,即它只创建单个新数组,子数组是共享的。
    • 所有从Object类继承而来的成员,Object中唯一没有被继承的方法就是clone方法。

    因此,数组具有与下面的类相同的public域和方法:

    class A<T> implements Cloneable,java.io.Serializable {
        public final int length = X;
        public T[] clone() {
            try{
                return (T[])super.clone();
            } catch (CloneNotSupportedException e) {
                throw new InternalError(e.getMessage());
            }
        }
    }

    注意:在上面例子中,如果数组真的以这种方式实现,那么其中向T[ ]的强制类型转换会产生非受检警告。

    从上面可以知道,数组是可克隆的

    class Test1 {
        public static void main(String[] args) {
            int ia1[] = {1,2};
            int ia2[] = ia1.clone();
            System.out.print((ia1 == ia2) + " ");
            ia1[1]++;
            System.out.println(ia2[1]);
        }
    }

    这个程序会产生下面的输出:
    false 2
    该输出展示了ia1和ia2所引用的数组元素是不同的变量。

    下面的例子说明多维数组克隆后共享子数组:

    class Test2 {
        public static void main(String[] args) throws Throwable {
            int ia[][] = { { 1, 2 }, null };
            int ja[][] = ia.clone();
            System.out.print((ia == ja) + " ");
            System.out.println(ia[0] == ja[0] && ia[1] == ja[1]);
        }
    }

    这个程序会产生下面的输出:
    false true
    该输出展示了 int[ ] 数组 ia[0] 和 int[ ] 数组 ja[0] 是同一个数组。

    3.数组的Class对象

    每个数组都与一个Class对象关联,并与其他具有相同元素类型的数组共享该对象。尽管数组类型不是类,但是每一个数组的Class对象起到的作用看起来都像是:

    • 每个数组类型的直接超类都是Object。
    • 每个数组类型都实现了Cloneable 接口和 java.io.Serializable 接口

      下面的代码用于测试上面的特点:

    package com.test;
    
    class A {
    
    }
    
    class B extends A implements Comparable<B>{
    
        @Override
        public int compareTo(B o) {
            return 0;
        }
    
    }
    public class Test2 {
        public static void main(String[] args) throws Throwable {
            B[] ba = new B[2];
            B b = new B();
            B[] ba1 = new B[2];
            //测试数组的Class对象是共享的
            System.out.println(ba == ba1);
            System.out.println(ba.getClass() == ba1.getClass());
            //测试数组ba和b的Class对象是否一样
            System.out.println(ba.getClass() + " | " + b.getClass());
            //测试数组ba和b的超类是否一样
            System.out.println(ba.getClass().getSuperclass() + " | " + b.getClass().getSuperclass());
    
            //测试数组ba和b实现的接口分别是什么
            for(Class<?>c : ba.getClass().getInterfaces())
                System.out.println("Superinterfaces: " + c);
            System.out.println("-----------");
            for(Class<?>c : b.getClass().getInterfaces())
                System.out.println("Superinterfaces: " + c);
        }
    }
    

    上面程序输出是:
    false
    true
    class [Lcom.test.B; | class com.test.B
    class java.lang.Object | class com.test.A
    Superinterfaces: interface java.lang.Cloneable
    Superinterfaces: interface java.io.Serializable
    - - - - - - - - - - -
    Superinterfaces: interface java.lang.Comparable

    其中,字符串“[Lcom.test.B”是“元素类型为com.test.B的数组”的Class对象的运行时类型签名

    根据上面的输出结果,可得出以下总结。

    • 数组的Class对象是共享的。

    • 虽然每个数组都与一个 Class 对象关联,但数组的Class对象并不等于数组元素的Class对象
      从上面这个输出可以看出:class [Lcom.test.B; | class com.test.B

    • 数组的类型是Object类的子类,并且数组的类型和数组元素的类型不一样。
      如上面的输出中, B[ ] 的超类是Object,而B的超类是A。B[ ]类型实现的是Cloneable 和 Serializable 接口,而B类实现的是Comparable 接口。

    展开全文
  • Java数组引用类型内存分配

    千次阅读 2015-03-19 10:50:38
     在上一篇中,我们已经了解了数组,它是一种引用类型,本篇将详细介绍数组的内存分配等知识点。数组用来存储同一种数据类型的数据,一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间...
  •  数据类型【】 数组名称 = new 数据类型 【长度】  eg:声明并开辟一个长度为5的数组 int[ ] data = new int[5];  a.数组通过下标索引来取得元素,下标默认从0开始。数组下标超出数组长度,数组越界异常(运行...
  • Java数组元素为基本数据类型时,数组中的所有元素都是基本数据类型, Java数组元素为引用类型时,数组中的所有元素都是对象。
  • 有关java数组强制类型转换的问题

    千次阅读 2019-03-26 10:38:24
    会报异常Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to java.base/[Ljava.lang.String; */ Object[] newArray = new Object[]{"AAA","BBB"}; ...
  • 引用类型——Java数组

    千次阅读 2016-05-10 15:49:32
    数组: 一组相关数据的集合,实际上就是一连串的变量,可以分为:一维数组、二维数组、多维...Java中的数组必须先初始化,然后才可以使用。 所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值。
  • Java 数组类型

    千次阅读 2019-12-24 00:31:55
    理解数组
  • Java数组转List的三种方式及对比

    万次阅读 多人点赞 2018-03-18 00:10:04
    本文介绍Java数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。
  • JAVA 数组类型

    2015-03-15 19:06:49
    4.5 数组类型 数组是编程语言中最常见的一种数据结构,它可用于存储多个数据,一个数据被称为数组元素,通常可通过数组元素的索引来...Java语言的数组则具有它特有的特征,下面将详细介绍Java语言的数组。 4.5.1
  • Java数组引用和对象

    2019-11-05 19:01:44
    Java中,数组其实是引用类型(reference) 什么是引用? 引用就是通过一个类似于指针的东西,指向内存中的某一个区域,引用是用来找到对象和线索的 比如:通过数组的引用,我们可以找到数组下标中的某一个基本数据...
  • JAVA 数组引用

    千次阅读 2018-05-08 19:10:40
    数组属于引用型变量,因此两个相同类型数组如果具有相同的引用,它们就有完全相同的元素。public class Hello { public static void main(String[] args) { int a[]= {1,2,3,4}; int b[]= {100,200,300}; ...
  • 新手小白学JAVA 数组 数组工具类 二维数组

    万次阅读 多人点赞 2021-04-02 08:28:55
    数组Array,标志是[ ] ,用于储存多个相同类型数据的集合 想要获取数组中的元素值,可以通过脚标(下标)来获取 数组下标是从0开始的,下标的最大值是数组的长度减1 1.2 创建数组 数组的创建方式一般分为动态初始化和...
  • Java数组

    千次阅读 多人点赞 2018-07-28 09:59:47
    数组引用类型数组型数据是对象(object),数组中的每个元素相当于该对象的成员变量。 数组是多个相同类型数据的组合,实现对这些数据的统一管理。一个数组实际上就是一连串的变量,数组按照使用可以分为一维数组...
  • 引用数据类型{类【class】;接口【interface】;数组【[ ]】} 两种不同数据类型的区别: 基本数据类型:变量存储在栈中;栈的特点是存储空间小,但是存取速度快 引用数据类型:变量存储在堆中...
  • java数组

    千次阅读 2019-07-18 20:59:36
    java数组 数组是什么呢? 数组是一种最简单的复合数据类型,它是有序数据的集合,数组中的每个元素具有相同的数据类型,可以用一个统一的数组名和不同的下标来唯一确定数组中的元素。根据数组的维度,可以将其分为一...
  • java 数组

    2020-02-15 20:40:33
    java 数组1. 数组的定义2.数组的下标 1. 数组的定义 数据类型[ ] 数组名 = new 数据类型[容量]; 赋值左侧 数据类型: ... 明确告知编译器,数组名是一个【引用数据类型数组名: 1. 操作数据非...
  • type 为 Java 中的任意数据类型,包括基本数据类型和引用类型, arrayName 为数组名,必须是一个合法的标识符,[ ] 指明该变量是一个数组类型变量。 例如: //第一种定义数组方式 int[] demo...
  • Java中的数组引用赋值

    万次阅读 2019-09-20 17:39:01
    Java中的数组引用赋值 这里将以Java中的冒泡排序为例进行分析 引用赋值不是简单的赋值操作,而是能够通过对对象b进行赋值操作从而对对象a进行修改值的行为。 //这是一种简单的将数组n中的值对应赋给数组num int i; ...
  • Java 数组

    千次阅读 2018-05-24 14:55:06
    Java 语言中提供的数组是用来存储固定大小的同类型元素。你可以声明一个数组变量,如 numbers[100] 来代替直接声明 100 个独立变量 number0,number1,....,number99。本教程将为大家介绍 Java 数组的声明、创建和...
  • java 数组类型

    千次阅读 2014-05-07 10:52:10
    对于基本类型而言,他们的类型就是 "class [*" * 代表他们的数据类型的第一个大写字母,不过 long[] 除外,因为 L 被用在了引用类型上了,所以就使用了 J 来作为 long[] 的类型,对于多维数组来说,每一个维度使用[ ...
  • 数组类型[] 数组名称 = new 数组类型[长度] 例:开辟一个长度为5的字符型数组: char[] arr = new char[5]; 数组是通过下标索引来取得元素,下标默认从0开始,数组下标超过数组长度就会发生数组越界异常(属于运行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 359,813
精华内容 143,925
关键字:

java数组引用类型

java 订阅