有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java中对象的名称意味着什么(数组、ArrayList)

我正逐渐从C语言转向java语言编程。在这样做的过程中,我在理解以下场景时感到困惑: 我有以下Java代码:

ArrayList<Integer> myList = new ArrayList<Integer>();

     for(int j = 0 ; j < 10 ;j++){

          myList.add(j);
    }

    System.out.println(myList);

  the o/p is:
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

根据我的理解,这里有一个ArrayList类型的对象(myList)

现在,我尝试对数组对象执行相同的操作:相同的代码,但将Arraylist替换为数组:

  int [] Arr = new int[]{1,2,3,4,5,6,7,8,9,10};

    System.out.println(Arr);

我得到垃圾值。为什么会这样?Array和ArrayList的区别是什么? 在C中,数组的名称有点像指针。(它有第一个元素的地址),那么在Java中,仅仅是对象的名称意味着什么呢? 地址或参考? 有什么区别? 为什么在Array和ArrayList的情况下会得到不同的结果


共 (3) 个答案

  1. # 1 楼答案

    在Java中,所有事物都是指针,但根据变量指向的内容,行为可能会发生变化

    int[] Arr = new int[]{1,2,3,4,5,6,7,8,9,10};
    

    int[]是一个基元类型(不是类类型)的数组,并且它不包含任何关于其“字符串表示”的信息,因此当您想要像您所做的那样打印变量(System.out.println(Arr);)时,打印出来的只是适合任何类型对象的字符串表示,比如它的哈希代码(它不是垃圾)

    在以下情况下:

    ArrayList<Integer> myList = new ArrayList<Integer>();
    

    您正在创建(通用)类ArrayList的对象<>;:这将覆盖方法(C中的函数)toString(),该方法指定如何优雅地打印ArrayList本身的内容(该方法非常基本:它只需迭代包含的所有项,创建一个字符串并打印它)

    调用System.out.println(myList);时,将隐式调用方法toString()(返回字符串),因此将打印该方法创建的字符串,如图所示

  2. # 2 楼答案

    虽然问题的所有部分都在不同的帖子中得到了回答,但我想谈谈你的具体措辞

    首先,建议您将列表类型声明为接口,并将其初始化为实现

    List<Object> list = new ArrayList<Object>();
    List<Object> list = new ArrayList<>(); // JDK 7 or later allows you to omit the generic type.
    

    您可以使用多个实现(ArrayListLinkedList…)实现List接口。见the collection tutorial

    What is the difference between Array and ArrayList?

    ArrayList是一个,请参见API。它作为List接口的实现,请参见API。这些是Java集合框架的一部分

    数组不像ArrayList那样是,但数组和类的实例都是对象。小心使用大写字母Array,因为它是一个different class

    I get garbage values. Why is this so?

    Why do I get varied results in case of Array and ArrayList?

    这与println方法有关。它自动调用传递给它的参数的toString方法。toString方法是为Object类定义的,该类超类所有其他类,因此它们都继承它。除非子类重写继承的方法,否则它将保留其超类的实现。让我们看看它对Object的作用:

    public String toString()

    Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

    The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

    getClass().getName() + '@' + Integer.toHexString(hashCode())

    我的。如您所见,这是打印数组变量时得到的“垃圾”。由于数组不是类,它们不能重写此方法(数组可以调用Object的所有方法,尽管它们不以通常的方式将其子类化)。但是Object的子类AbstractCollection覆盖了以下内容:

    public String toString()

    Returns a string representation of this collection. The string representation consists of a list of the collection's elements in the order they are returned by its iterator, enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (comma and space). Elements are converted to strings as by String.valueOf(Object).

    由于ArrayListAbstractList的一个子类,而AbstractCollectionAbstractCollection的一个子类(并且它们不会覆盖toString),因此您可以得到“简洁但信息丰富的表示,便于阅读”

    关于JVM如何处理数组,有一些很好的观点,但是为了从开发人员的角度理解输出,这就足够了

  3. # 3 楼答案

    在java中,变量的名称是对该变量的引用(如果与c++相比)。当您在myList上调用println时,实际上您调用了ArrayListtoString()方法,该方法继承自Object,但被重写以提供有意义的打印。此方法继承自Object,因为ArrayList是一个类,所有类都扩展了Object,因此具有方法toString

    本机数组是原语,但没有这种特性,因此得到的是默认的对象表示形式(虚拟内存地址)

    您可以尝试以下方法:

    public class TestPrint {
        private String name;
        private int age;
    
        public TestPrint(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() { return name;}
    
        public int getAge() { return age; }
    }
    

    然后尝试println(new TestPrint("Test", 20));-这将打印与数组类似的内容

    现在,添加一个toString()方法:

    @Override
    public String toString() {
      return "TestPrint Name=" + name + " Age=" + age;
    }
    

    然后再次调用println(new TestPrint("Test", 20));,您将得到TestPrint Name=Test Age=20作为输出

    为了进一步解释为什么会发生这种情况,方法println有一个重载,它接受类型为Object的内容。这个方法的实现调用toString来打印对象(当然这是非常简单的解释)