【发布时间】:2009-02-19 10:37:50
【问题描述】:
在 C++ 中,如果我在调用方法之后声明方法,我将无法使用它。
此顺序在 Java 或 C# 等其他语言中是否重要?
【问题讨论】:
-
请针对 Java 和 C# 分别发布问题。就目前的形式而言,您的询问对于 Stack Overflow 来说过于宽泛。
在 C++ 中,如果我在调用方法之后声明方法,我将无法使用它。
此顺序在 Java 或 C# 等其他语言中是否重要?
【问题讨论】:
方法的声明顺序在 C# 或 Java 中无关紧要。同样,在它使用的变量之前或之后声明方法也没有关系。
变量的声明顺序可能很重要,但是,当它们被初始化时,一个依赖于另一个。例如(C#):
using System;
class Test
{
static int x = 5;
static int y = x;
static void Main()
{
// Prints x=5 y=5
Console.WriteLine("x={0} y={1}", x, y);
}
}
但是:
using System;
class Test
{
static int y = x;
static int x = 5;
static void Main()
{
// Prints x=5 y=0
Console.WriteLine("x={0} y={1}", x, y);
}
}
Java 阻止了这种精确的情况,但它很容易模仿:
public class Test
{
static int y = getInitialValue();
static int x = 5;
public static void main(String args[])
{
System.out.println("x=" + x + " y=" + y);
}
static int getInitialValue()
{
return x;
}
}
在 C# 中,当您涉及部分类时,事情会变得更加混乱。初始化在 C# 中按文本顺序进行,但当您有多个文件贡献于同一个类时,该顺序并未完全定义。
不用说,尽可能避免这种情况!
【讨论】:
没有。
【讨论】:
不,编译器执行两次。
【讨论】:
在 Java 和 c# 中没有单独的方法声明。
方法的声明是通过它的实现来完成的。您还不需要跟踪文件包含,这样只要类在同一个命名空间中,它们就可以相互了解。
【讨论】:
对于 Java,权威答案隐藏在 Java 语言规范(“JLS”第 3 版,可在线免费查看)的第 1 章(简介)中:
声明顺序仅对局部变量、局部类以及类或接口中字段的初始值设定项的顺序很重要。
【讨论】:
我不确定c#,但是在java中你可以。
【讨论】:
C# 中没有。
【讨论】:
C# 和 Java 都没有。
【讨论】:
该变量应该可以在使用它的方法中访问。在使用之前或之后声明都没有关系。
【讨论】:
有一种棘手的情况,可以在调用点之后在词法上声明要调用的函数,但不能在语义上声明。这是因为类被认为是完全定义在类成员函数体中的。
$9.2.2 - “一个类被认为是一个 完全定义的对象类型 (3.9) (或完整类型)在结束 } 的 类说明符。班内 成员规范,类是 在功能内被认为是完整的 主体,默认参数和 构造函数初始化器 (包括嵌套中的这些东西 类)。否则视为 在自己的类中不完整 成员规范。”
struct A{
void f(){g();} // OK to call 'g' even if the compiler has not seen 'g' as yet
void g(){};
};
int main(){
A a;
a.f();
}
【讨论】:
在某些极端情况下,Java 中方法/构造函数的顺序确实很重要:
class Callee {
private static void bar(int i) { } // compilation error if first
public static void bar(String s) { } // ok if this method is first
}
class Caller {
private void foo() { Callee.bar(bar()); }
private <T> T bar() { return null; }
}
【讨论】:
这些答案相互矛盾,使事情难以理解。最佳实践是以常识的时间顺序声明您的方法、变量等,以免混淆,这适用于所有编程语言。您的 main 将始终是第一个,因此可以在开头或结尾,但是,您仍然应该从 main 开始,并且当您在 main 中调用方法时,它应该是 main 之后的下一个方法,依此类推。至少对我来说,这最有意义,并且使代码最易读(cmets 也有很大帮助,因为让我们面对现实吧,代码真的很乱)。我不是编码专家,但我知道任何算法的最佳实践是根据需要将其分解为尽可能多的简单步骤(请使用 cmets)。这没有意义:
final List<int[]> intArrays = Arrays.stream(testarray).collect(Collectors.toList());
final List<Integer> integers = intArrays.stream().flatMap(z ->
Arrays.stream(z).boxed()).collect(Collectors.toList());
unless you add comments like:
final List<int[]> intArrays = Arrays.stream(testarray).collect(Collectors.toList());
// this makes a List (of ints) variable type that cannot be changed based on the stream of
//(the testarray in this case) and uses the Collector method to add the ints
//to intArrays (our variable name)
final List<Integer> integers = intArrays.stream().flatMap(z ->
Arrays.stream(z).boxed()).collect(Collectors.toList());
// I would have to look this up, because I honestly have no clue what it does exactly.
就像我说的,代码基本上是乱码。无论您使用哪种语言,都可以帮助您自己和其他可能查看您的代码并按逻辑顺序编写代码的人。 (同样,请使用 cmets!稍后您会感谢我的。)
【讨论】: