2011-10-23 69 views
1

数组参数声明导致调用发生的语法错误。然而,主要方法使用String []而不是String ...我如何理解这种不一致?为什么Java的主要方法使用String []而不是String dot dot dot

package domain.test; 

import utilities.CConsole; 

public class Tester { 
    public static void main(String[] args) 
    { 
     Test1 t = new Test1(); 
     t.method1(0); // the array will exist but have a length of zero 
     t.method1(0, (Object[])null); // the array will not exist 
     t.method1(0, "a"); 
     t.method1(0, "a", "b"); 
     CConsole.pw.format("\n"); 

     t.method2(0); // the array will exist but have a length of zero 
     t.method2(0, (String[])null); // the array will not exist 
     t.method2(0, "a"); 
     t.method2(0, "a", "b"); 
     CConsole.pw.format("\n"); 
    } 
} 

class Test1 { 
    void method1(int number, Object... args) // Object[] causes syntax errors 
    { 
     if (args == null) 
      CConsole.pw.format("args == null\n"); 
     else 
     { 
      CConsole.pw.format("args != null "); 
      CConsole.pw.format("args.length %d\n", args.length); 
     } 
    } 

    void method2(int number, String... args) // String[] causes syntax errors 
    { 
     if (args == null) 
      CConsole.pw.format("args == null\n"); 
     else 
     { 
      CConsole.pw.format("args != null "); 
      CConsole.pw.format("args.length %d\n", args.length); 
     } 
    } 
} 

如何解释不一致性?

以下内容适用于表示编译的人员:要获取此错误更改method1()以使用Object []。

总结编辑:这一课似乎是这样的。正如@Andrew Barber强调的那样,String ...与String []不同。他们通常可以互换,所以不要试图以同样的方式对待他们(尽管我可以说出他们为什么看起来可以互换的原因)。他们 main()的情况下可以互换。在main()的情况下,有些人可能会称这种糖。

+2

在函数参数中使用''''''是有效的,它不应该产生语法错误。它打印什么错误/ – birryree

+0

不,只需复制代码并尝试。 – H2ONaCl

+1

为什么它应该给出语法错误?使用String []作为参数没有什么问题 – ryanprayogo

回答

2

通常,您可以使用可变参数来指定一个方法将可变数量的参数作为输入的事实。因此,集合,数组和简单的单个对象可以在java中互换地发送。这简化了方法,但有一些问题。

可变参数工作自然如果

1)它们是在一个方法的签名 2)类型正在定义作为VAR ARG数据的END是线性的(即,阵列或集合)。如你所见,main(String [] args)因此非常适合使用var args(也就是说,args位于方法的末尾,它是最后一个参数,所以它实际上是相同的作为声明“String ... args”作为最后一个参数)。为了更好地理解它们,我会建议编写这两种方法,并且看看编译器做了什么:

所以要回答你的问题:你很幸运:)你的方法发送了一个可变数量的参数给main方法,并且新的版本的Java允许你摆脱var args作为main的输入。

+0

“正如你所看到的,main(String [] args)因此非常适合使用var args。”这是含糊不清的。但是,最后一段是接受的原因。 – H2ONaCl

+1

@broiyan:不幸的是,最后一段看起来不准确,因为你没有任何方法调用主要方法。 –

+0

我有一个linux操作系统和一个Eclipse IDE调用它,所以它似乎相关。 – H2ONaCl

5

可用性语言是在较新版本的语言中添加的。如果您需要main,您可以在支持可变参数的Java版本上使用String ...而不是String[]

+0

为什么main(String [] args)不是语法错误? – H2ONaCl

+6

@broiyan因为这个语法没有问题。 – EJP

+0

但是,在调用时不允许其他方法的语法。 – H2ONaCl

-4

String []表示一个字符串数组。只有一个字符串是不够的,因为你可能想用更多的参数运行你的程序。所谓的“不一致性”对于面向对象技术来说是正常的。来自不同类的两个对象可能会有不同的表现。只有初学者称这种“不一致”。阅读关于面向对象的范式,你就能自己找到答案。

+2

'字符串...'不是一个字符串。出于所有实际目的,它的行为与String []相同。正如trinithis指出的那样,在main()中没有使用的真正原因是'main()'早于Java引入可变参数支持很长一段时间。 – aroth

+0

这个问题与OOP无关。 – EJP

+0

@aroth你确实可以声明'public static void main(String ... args)'。 – EJP

3

我认为你对什么是有效的数组参数感到困惑。参数varargs意味着你可以传递0或更多的任何类型。如果没有歧义,您可以传递一个数组,数组的内容将被扩展为varargs参数。

另一方面,数组参数意味着您必须只传递一个数组。当您用Object[]String[]替换可变参数参数时,示例中的错误来自您如何调用方法。例如:

t.method1(0, "a", "b"); 

这是精细的可变参数调用,但只要你切换的可变参数参数的Object[],前面的方法调用将需要更改为:

t.method(0, new Object[]{"a", "b"}); 

t.method(0, new String[]{"a", "b"}); 

由于数组允许多态性。相反,如果你的方法使用可变参数,传递一个数组就可以工作得很好。所以你看,关于main方法没有不一致。 String[]String...可以正常工作,因为您看到的问题涉及的方法是,称为,而不是定义的

更新:既然你似乎在寻找的细节问题,对5.2 Virtual Machine Start-Up的JVMS说

Java虚拟机通过调用 方法主要一些指定的类,它传递一个开始执行单个参数,这是一个字符串数组 。

和上8.4.1 Formal Parameters,它说

如果最后正式的参数是它被认为限定类型T []的形式参数类型T的元数可变参数, 。方法 然后是一个可变的arity方法。否则,它是一个固定的方法 方法。变量arity方法的调用可能包含比形式参数更多的实际参数表达式。所有实际参数 表达式不对应于 之前的形式参数,将会评估变量arity参数并将结果存储到将传递给方法调用的数组中。

因此主方法总是通过一个String[]在应用程序启动时被调用,并且一个可变参数参数总是由相应的方法作为一个阵列接收,所以没有不一致的任何地方。

+1

@broiyan:更新。如果你想要的话,你可能首先要求它。 –

+0

它始终是一个String [],然而main(String ... args)的作品。我想这是真正的不一致。 (由于回答者的努力,最初的不一致已得到解决。) – H2ONaCl

+0

仔细阅读第二个报价。除了'String ...'允许源代码中的某些语法糖之外,'String ...'等同于'String []'的所有意图和目的。没有矛盾。 –

0

简短且唯一正确的答案是您可以使用其中之一。

+0

我想你的意思是你可以在'main()'中使用,而不改变操作系统。只要您不期望任何“人工协助”,您可以使用其他方法。 – H2ONaCl

+0

@broiyan这不仅是我的意思,这正是我所说的,没有与操作系统无关的无关紧要的事情,这是隐含的,我没有提到它。你关于'人工协助'的声明是完全错误的。如果您使用......您可以在呼叫站点使用可变参数*或*数组,这就是我所说的“人工协助”。 – EJP