从类内部调用对象的方法与在方法内调用方法

时间:2016-09-20 09:50:21

标签: java

这可能是一个非常基本的问题,但在我的Java学习的这个阶段让我感到困惑。 我有以下代码:

    package com.soti84;

    import java.util.ArrayList;

    public class InvokeMethod {

    public static void main(String[] args) {

    ArrayList<String> exams= new ArrayList<String>();
    exams.add("Java"); 
    exams.add("C#");    

    }           

    }

如果我移动实例化ArrayList对象的行以及该方法外部对该对象的调用,则创建该对象的行很好,但不允许对该对象执行add()方法调用。那是为什么?

    package com.soti84;

    import java.util.ArrayList;

    public class InvokeMethod {
    ArrayList<String> exams= new ArrayList<String>();
    exams.add("Java"); 
    exams.add("C#");    

    public static void main(String[] args) {

    }   

    }

感谢。

4 个答案:

答案 0 :(得分:3)

您无法在方法之外执行该代码。如果你想这样做,你需要初始化块或静态块。

public class InvokeMethod {
    ArrayList<String> exams= new ArrayList<String>();
    {
      exams.add("Java"); 
      exams.add("C#"); 
    }

现在,当您创建实例时,该块将被执行。如果您的变量是静态的,则可以将该块设置为静态(只需在该块之前添加static)。当您的类初始化时,将执行静态块。当您需要填充的静态列表/地图时,这些块可以非常方便。当然,编程方便的一切都可能是一种不好的做法,同样在这里,这些块被一些人所厌恶,它们可能非常危险并导致难以发现的错误(主要是关于执行的顺序)。

答案 1 :(得分:1)

在这两个例子中,你试图完成两件完全不同的事情。

在第一个示例中,您在ArrayList方法中声明了main,因此列表的范围将只是此方法。封闭类与ArrayList完全没有关系。

在第二个中,您尝试在类exams中创建名为InvokeMethod的数据成员。这意味着,这个类的每个实例都有自己的列表。

添加元素不起作用,因为“out of the methods”只能声明和初始化。要解决此问题,您可以使用initialization block

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();
    {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {
    }   
}

或者,类的构造函数:

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();

    public InvokeMethod() {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {

    }   
}

注意:您还可以通过main类的实例从InvokeMethod方法检索此列表:

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();

    public InvokeMethod() {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {
        InvokeMethod invokeMethod = new InvokeMethod();
        System.out.println(invokeMethod.exams.toString());
        invokeMethod.exams.add("Delphi");
        System.out.println(invokeMethod.exams.toString());
    }   
}

将打印

[Java, C#]
[Java, C#, Delphi]

答案 2 :(得分:0)

那是因为“你是从函数/方法之外调用它”

ArrayList<String> exams= new ArrayList<String>();

上面的行表示您将其声明为Object的属性。这意味着您只能在方法中访问它。

如果您要将以下内容放入主

exams.add("Java"); 
exams.add("C#");  

这应该可以正常工作,尽管你在方法之外宣布了“考试”。

答案 3 :(得分:0)

根据Java language specification,类主体声明具有实例初始化器,但没有方法调用。因此,在您的示例中,ArrayList<String> exams= new ArrayList<String>();允许在类体内,但不允许exams.add("Java");

JLS摘录:

ClassBody:
    { ClassBodyDeclarationsopt }

ClassBodyDeclarations:
    ClassBodyDeclaration
    ClassBodyDeclarations ClassBodyDeclaration

ClassBodyDeclaration:
    ClassMemberDeclaration
    InstanceInitializer
    StaticInitializer
    ConstructorDeclaration

ClassMemberDeclaration:
    FieldDeclaration
    MethodDeclaration
    ClassDeclaration                        
    InterfaceDeclaration
    ;