对对象数组的引用是否指向同一数组的第一个元素?在java中

时间:2018-09-15 10:24:59

标签: java arrays oop pointers reference

我有一个疑问,在Java中的此语句中

class Country {

    public Country(String countryName) {
        this.countryName = countryName;
        this.states = new ArrayList<>();
    }

    String countryName;
    List<State> states;

}

class State {

    public State(String stateName) {
        this.stateName = stateName;
        this.cities = new ArrayList<>();
    }


    String stateName;
    List<City> cities;
}

class City {
    public City(String cityName) {
        this.cityName = cityName;
    }

    String cityName;
}

class Geography {
    String countryName;
    String stateName;
    String cityName;
}


List<Country> buildFromGeographies(List<Geography> geos) {

    List<Country> result = new ArrayList<>();

    for (Geography geo : geos) {
        Optional<Country> country1 = result.stream().filter(country -> country.countryName.equals(geo.countryName)).findFirst();
        Country country = country1.orElseGet(() -> {
            Country newOne = new Country(geo.countryName);
            result.add(newOne);
            return newOne;
        });

        Optional<State> state1 = country.states.stream().filter(state -> state.stateName.equals(geo.stateName)).findFirst();
        State state = state1.orElseGet(() -> {
            State newOne = new State(geo.stateName);
            country.states.add(newOne);
            return newOne;
        });

        // taking for granted there is no duplicates in your data set
        state.cities.add(new City(geo.cityName));
    }

    return result;

}

此语句将在内存中存储多少引用,并且A z[]=new A[5]; 引用指向z

1 个答案:

答案 0 :(得分:2)

给出:A[] x = new A[5];(不要写A x[];它是合法的Java,但完全不是惯用语言。请把它看作是假冒的风格。就像误输入代码一样)。假设它在方法内部(因此,它是一个局部变量声明,而不是字段声明)。

这将创建一个名为“ x”的新局部变量,该局部变量仅限于指向对象,并且只能指向A[]null的实例,并且没有其他内容,并且均由编译器进行了验证和运行时。它还会在堆上实例化一个新的数组对象,并将x变量设置为指向此新创建的对象。

此指针变量本身需要占用一些空间(4或8个字节,具体取决于VM),但是它将像C中一样位于堆栈中。

那么,new A[5]在内存方面有何作用?

它将创建一个新对象来表示数组本身。该对象包含以下信息:我有多少个元素,我的组件类型是什么。再次与C不同,C仅具有指向数组数据结构的指针,因此您不知道其中可能有什么数据,也不知道其中有多少数据。在Java中,情况并非如此,但是信息(长度和类型)意味着您需要将其显式存储在内存中。您可以观察到:x.length将返回5,而x.getClass().getComponentType将返回A.class。在64位VM上,此对象总共约占24个字节(大小为4个字节,组件类型的指针为8个字节,并抛出了一些额外的字节,因为该事物需要标识它代表的是数组)。 / p>

在这24个字节之后,有5个“插槽”,每个插槽占用的字节数与组件类型所需的字节数相同。那个多少钱?取决于A是什么。

如果A为:byteshortintlongfloatdouble,{{1 }},char或其他任何内容。

然后,组件大小(以字节为单位)分别为:1、2、4、8、8、4、8、2、1和X,其中X为4或8,具体取决于VM。如今,几乎总是有8个(64位VM)。

在执行期间,VM可能会在内存表中注入一些空白,因为现代的CPU确实非常不喜欢处理64位边界上的东西。 C编译器做同样的事情。