方法调用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
由于静态方法调用不是ClassMemberDeclaration
, InstanceInitializer
, StaticInitializer
和ConstructorDeclaration
,因此不允许它直接存在于类体内。
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,因为你没有做任何事情(既没有上下文也没有将值赋给私有变量)