方法调用Java类

我今天开始在Eclipse中编写一段代码,我开始是这样的:

public class MyClass { System.currentTimeMillis(); } 

(忽略我不是直接思考等事实……)

我得到这个编译错误:

令牌“currentTimeMillis”上的语法错误,此令牌后预期的标识符

如果我将该语句更改为赋值语句,它可以工作:

 long time = System.currentTimeMillis(); 

当然,如果放在方法体内并且也放在类体内的块内,它不会导致错误。

为什么是这样? 是否有一些编译器级规则表明只有赋值语句或声明应存在于类体内?

TIA

类主体只能包含声明。

具体来说, JLS的第8.1.6节定义了这样的类体:

类主体可以包含成员的声明,即字段(第8.3节) ,类(第8.5节) ,接口(第8.5节)和方法(第8.4节) 。 类主体还可以包含实例初始值设定项(第8.6节) ,静态初始化程序(第8.7节)和类的构造函数声明(第8.8节) 。

     ClassBody:
       {ClassBodyDeclarations opt } 
ClassBodyDeclarations: ClassBodyDeclaration ClassBodyDeclarations ClassBodyDeclaration
ClassBodyDeclaration: ClassMemberDeclaration InstanceInitializer StaticInitializer ConstructorDeclaration
ClassMemberDeclaration: FieldDeclaration MethodDeclaration ClassDeclaration InterfaceDeclaration ;

如您所见,无论如何都没有语句,因此类主体可能不会直接包含语句。

如果你考虑一下,它是有道理的:该代码应该在哪个点执行? 没有任何背景可以告诉你这一点,所以没有任何意义。

这是非法的。 在类体中,您只能拥有:块,字段,构造函数,方法和类

你的不是。 那你还期望它做什么呢? 如果希望在实例化类时执行它,则将其放在块中:

 { System.currentTimeMillis(); } 

试试这种方式:

 public class MyClass { static { System.currentTimeMillis(); } } 

如果在静态语句中调用System.currentTimeMillis(),它就可以工作。 当类加载器加载类“MyClass”时,将调用静态块。

是否有一些编译器级规则表明只有赋值语句或声明应存在于类体内?

总之一句:是的。 在类主体级别,您可以拥有实例和静态成员变量声明,方法声明,嵌套类,对象初始化块,静态初始化块和注释。 根据定义,就是这样。

语言的“编译器级规则”称为语法

是否有一些编译器级规则表明只有赋值语句或声明应存在于类体内?

是。 更具体地说,编程语言的句法规则通常被定义为一种forms语法,它规定了语法正确的程序是如何形成的。 在这种情况下, Java语言规范说:

 ClassBody: { ClassBodyDeclarationsopt } ClassBodyDeclarations: ClassBodyDeclaration ClassBodyDeclarations ClassBodyDeclaration ClassBodyDeclaration: ClassMemberDeclaration InstanceInitializer StaticInitializer ConstructorDeclaration 

由于静态方法调用不是ClassMemberDeclarationInstanceInitializerStaticInitializerConstructorDeclaration ,因此不允许它直接存在于类体内。

 long time = System.currentTimeMillis(); 

是一个实例变量,它在创建封闭对象时被初始化为当前时间。 有效

 System.currentTimeMillis(); 

是一个声明本身。 无效 ,outwith构造函数,方法,静态iniatilizer等。

您需要从方法内部调用代码,而不仅仅是单独调用代码。 例如

 public class MyClass { public static void main(String[] args) { System.currentTimeMillis(); } } 

以上仍然不会做任何事情,但这是合法的:-)

你没有得到该行的错误

 long time = System.currentTimeMillis(); 

因为您在类中指定了一个私有变量(很长时间)并将它们设置为默认值(System.currentTimeMillis())所以当您创建MyClass类的新实例时,该变量正在实例化。

只调用System.currentTimeMillis()只有nosense,因为你没有做任何事情(既没有上下文也没有将值赋给私有变量)