开发者

Method calls inside a Java class return an "identifier expected after this token" error

When I write the following code in Eclipse:

public class MyClass {
    System.currentTimeMillis();
}

I get this compile error:

Syntax error on token "currentTimeMillis", Identifier expected after this token

It works if I change that statement to an assignment statement:

long time = System.currentTimeMillis();

Of course, it doesn't cause errors if placed inside a method body or within b开发者_如何学Golocks inside the class body.

Why is this? Is there some compiler level rule that says that only assignment statements or declarations should be present inside the class body?


The class body can only contain declarations.

Specifically, § 8.1.6 of the JLS defines the class body like this:

A class body may contain declarations of members of the class, that is, fields (§8.3), classes (§8.5), interfaces (§8.5) and methods (§8.4). A class body may also contain instance initializers (§8.6), static initializers (§8.7), and declarations of constructors (§8.8) for the class.

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

As you can see, there are no statements in there anyway, so a class body may not directly contain a statement.

If you think about it, it makes sense: at which point should that code be executed? There is no context to tell you about that, so it makes no sense.


This is illegal. In the class body you can have only: blocks, fields, constructors, methods and classes

Yours is neither. And what would you expect it to do anyway? If you want it to be executed when the class is instantiated, then place it in a block:

{
    System.currentTimeMillis();
}


Try this way:

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

If you call System.currentTimeMillis() inside a static statement it works. The static block will be called when the class "MyClass" is loaded by the class loader.


Is there some compiler level rule that says that only assignment statements or declarations should be present inside the class body?

In a word: yes. At the class body level you can have instance and static member variable declarations, method declarations, nested classes, object initialization blocks, static initialization blocks, and comments. That's it, by definition.

The "compiler level rules" for a language are called its grammar.


You need to call your code from inside a method, not just on its own like that. E.g.

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

The above still won't do anything, but it's legal :-)


You dont get the error with the line

long time = System.currentTimeMillis();

because you are specifying a private variable inside the class (long time) and setting them to a default value (System.currentTimeMillis()) so when you make a new instance of the class MyClass, the variable is being instantiated.

calling only System.currentTimeMillis() just has nosense, because you arent doing nothin' (neither having a context or assigning the value to a private variable)


Is there some compiler level rule that says that only assignment statements or declarations should be present inside the class body?

Yes. More specifically, the syntactic rules of programming languages are usually defined as a formal grammar that specifies how syntactically correct programs are formed. In this case, the Java language specification says:

ClassBody:
    { ClassBodyDeclarationsopt }

ClassBodyDeclarations:
    ClassBodyDeclaration
    ClassBodyDeclarations ClassBodyDeclaration

ClassBodyDeclaration:
    ClassMemberDeclaration
    InstanceInitializer
    StaticInitializer
    ConstructorDeclaration

Since a static method call is not one of ClassMemberDeclaration, InstanceInitializer, StaticInitializer and ConstructorDeclaration, it's not allowed to be present directly inside a class body.


long time = System.currentTimeMillis();

is an instance variable, which gets initalized to the current time when the enclosing Object is created. Valid.

System.currentTimeMillis();

is a statement on its own. Invalid, outwith a constructor, method, static iniatilizer etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜