java变量参数列表中至少需要一个元素 [英] Requiring at least one element in java variable argument list

查看:25
本文介绍了java变量参数列表中至少需要一个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个代码结构中:

public MyClass(Integer... numbers) {
    do_something_with(numbers[]);
}

是否可以要求 numbers 至少包含一个条目,以便在编译时进行检查?(当然,在运行时,我可以只检查 numbers.length.)

is it possible to require that numbers contains at least one entry in such a way, that this is checked at compile-time? (At run-time, of course, I can just check numbers.length.)

显然我可以这样做:

public MyClass(Integer number, Integer... more_numbers) {
    do_something_with(number, more_numbers[]);
}

但这不会很优雅.

我想这样做的原因是为了确保子类不会简单地忘记调用这个构造函数,它会默认调用 super() 而没有列表中的数字.在这种情况下,我宁愿得到熟悉的错误信息:Implicit super constructor is undefined.必须显式调用另一个构造函数.

The reason I would like to do this is to make sure that a sub-class does not simply forget to call this constructor at all, which will default to a call to super() with no numbers in the list. In this case, I would rather like to get the familiar error message: Implicit super constructor is undefined. Must explicitly invoke another constructor.

是否有另一种方法可以实现相同的目标,例如一些 @-annotation 将该构造函数标记为非隐式?

Could there be another way to achieve the same, like some @-annotation that marks this constructor as non-implicit?

推荐答案

我想一种非常hacky 的方法是创建一个无参数方法并将其标记为已弃用.然后使用这两个标志进行编译:-Xlint:deprecation -Werror.这将导致任何不推荐使用的方法的使用都是编译时错误.

I suppose one incredibly hacky way to do this is to create a no-args method and mark it as deprecated. Then compile with these two flags: -Xlint:deprecation -Werror. This will cause any use of a deprecated method to be a compile time error.

编辑(在最初的答案之后很长一段时间):

edit (a long time after the initial answer):

一个不那么笨拙的解决方案是放弃 MyClass(Integer... numbers) 构造函数并用 MyClass(Integer[] numbers) 替换它(并添加一个私有无参数构造函数).它阻止编译器隐式使用超类构造函数,但没有任何参数,并为您提供编译时错误消息.

A less hacky solution would be to ditch the MyClass(Integer... numbers) constructor and replace it with MyClass(Integer[] numbers) (and add a private no-args constructor). It stops the compiler from being able to implicitly use the super class constructor, but without any args, and gives you a compile time error message.

./some_package/Child.java:7: error: constructor Parent in class Parent cannot be applied to given types;
    public Child(Integer[] args) {
                                 ^
  required: Integer[]
  found: no arguments
  reason: actual and formal argument lists differ in length

代价是你的调用语法会变得更加冗长:

The cost is your calling syntax will become a bit more verbose:

new Child(new Integer[] {1, 2, 3});

你当然可以编写一个辅助函数来帮助解决这个问题.

You can of course write a helper functions to help with this eg.

public static Child newInstance(Integer... numbers) {
    return new Child(numbers);
}

@SafeVarargs
public static <T> T[] array(T... items) {
    return items;
}

然后:

Child c0 = Child.newInstance(1, 2, 3);
Child c1 = new Child(array(1, 2, 3));

这篇关于java变量参数列表中至少需要一个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆