嵌套子类实例化声明 Java

Nested Subclass Instantiation Declaration Java

来自 JavaScript 的背景,我发现下面的代码有点过于健壮,包含多个语句;并且想知道如何简化代码,并在一条语句中完成所有操作。

Student 是超类,Friend 和 Schedule 是聚合到超类 ArrayList public 成员中的子类(它们不是嵌套的 类)。这是我当前的代码:

public static void main(String[] args) {

  // Subclass1 instantiation and declaration
  Friend friend_of_andy_1 = new Friend(1002, "Bob");
  ArrayList<Friend> andys_friends = new ArrayList<>();
  andys_friends.add(friend_of_andy_1);    // superclass member

  // Subclass1 instantiation and declaration
  Schedule schedule_of_andy_1 = new Schedule(1, "Yoga practice");
  ArrayList<Schedule> andys_schedule = new ArrayList<>();
  andys_schedule.add(schedule_of_andy_1); // superclass member

  // Superclass instantiation declaration with subclass objects in constructor argument
  Student student_andy = new Student(1001, "Andy", andys_friends, andys_schedule);

}

我想知道我是否可以做这样的事情,我 declare/instantiate 超类和子类 类 在一个语句中;这可能吗?

public static void main(String[] args) {

  Student student_andy = new Student(
    1001,
    "Andy",
    // instantiation of subclass
    ArrayList<Friend>[
      Friend(
        {
          1002,
          "Bob"
        }
      )
    ],
    ArrayList<Schedule>[
      Schedule(
        {
          1,
          "Yoga practice"
        }
      )
    ]
  )

};

首先,你只在一个地方使用了friend_of_andy_1,所以你可以去掉它:

List<Friend> andys_friends = new ArrayList<>();
andys_friends.add(new Friend(1002, "Bob"));

其次,如果您接受具有固定大小的列表,即您不能向其添加更多元素,则可以使用 Arrays.asList(), instead of creating an ArrayList:

List<Friend> andys_friends = Arrays.asList(new Friend(1002, "Bob"));

然后你可以对 Schedule 做同样的事情,并在 Student:

的创建中内联它
Student student_andy = new Student(1001, "Andy",
                                   Arrays.asList(new Friend(1002, "Bob")),
                                   Arrays.asList(new Schedule(1, "Yoga practice")));

如果列表必须可调整大小,则使用 ArrayList​(Collection<? extends E> c) 构造函数:

Student student_andy = new Student(
        1001,
        "Andy",
        new ArrayList<>(Arrays.asList(
                new Friend(1002, "Bob")
        )),
        new ArrayList<>(Arrays.asList(
                new Schedule(1, "Yoga practice")
        ))
);

当然还有您想要的格式,如果您更喜欢占用太多代码行的分解样式:

Student student_andy = new Student(
    1001,
    "Andy",
    new ArrayList<>(
        Arrays.asList(
            new Friend(
                1002,
                "Bob"
            )
        )
    ),
    new ArrayList<>(
        Arrays.asList(
            new Schedule(
                1,
                "Yoga practice"
            )
        )
    )
);

好的,所以,从本质上讲,您缺少的 JSON [footnote-1] 太多了?可以理解。

下面是在 Java 中创建实例的松散方法集合,因此看起来尽可能像 JSON。

1) 数组: 使用内联数组文字

它们在 Java 中稍微冗长一些,但几乎与 JSON 中的 [ ... ] 一样好,例如:

new int[]{1, 2, 3}

是整数数组的文字。

2) 对象: 定义适当的构造函数

如果你的 Friend 有一个构造函数 public Friend(int id, String name),那么初始化 Friend 真的很容易和愉快:

new Friend(1234, "Bob")

3) 更多对象,更快 使用工厂方法

如果定义了工厂方法,就可以去掉new。例如。如果你有

class Friend {
    ...
    static Friend friend(int id, String name) { return new Friend(id, name); }
}

那么你甚至可以去掉new。这在极少数情况下非常有用,您正在定义某种嵌入式 DSL,并且确实需要此构造函数一千次。

4) 列表: 使用 asList

您可以在 Java:

中使用 static imports 导入静态方法
import static java.util.Arrays.asList;

现在您可以使用方便的 asList,因此

asList(friend(2, "John"), friend(3, "Bob"))

给你一个朋友列表。

5) 映射: 使用带有初始化块的匿名子类。

这个看似疯狂的东西在java中起作用:

HashMap<String, Integer> hm = new HashMap<>{{
  put("foo", 10);
  put("bar", 20);
}};

这是因为内部一对大括号包含一个 初始化程序块 ,您可以在其中调用 this.

上的方法

好的,现在您可以轻松创建:

  • 原始的东西:字符串,ints,doubles
  • 用户定义的对象(使用构造函数和工厂方法)
  • 数组
  • 列表
  • 地图

这应该足以在 Java.

中创建临时的 json 式数据结构

现在,假设所有构造函数都已到位,您的代码将变为:

import static java.util.Arrays.asList;

...

Student student_andy = new Student(
  1001,
  "Andy",
  asList(new Friend(1002, "Bob")),
  asList(new Schedule(1, "Yoga practice"))
)

我们这里没有使用地图,所以带有初始化块的提示只是一个奖励。

[footnote-1] 更准确地说:似乎您缺少 JavaScript 的片段,它允许轻松初始化那些规范的对象映射到 JSON 个对象。 JSON当然不是Java脚本。感谢@Andreas 指出这一点。