簡體   English   中英

從類內部與從方法內部調用對象的方法

[英]Calling a method on an Object from within a Class vs from within a method

這可能是一個非常基本的問題,但在我學習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) {

    }   

    }

謝謝。

您根本無法在方法之外執行該代碼。 如果要執行此操作,則需要初始化程序塊或靜態塊。

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

現在,創建實例時將執行該塊。 如果您的變量是靜態的,則可以將該塊設為靜態(只需在該塊之前添加static )。 初始化類時,將執行靜態塊。 當您需要填充的靜態列表/映射時,這些塊會非常方便。 當然,所有方便編程的東西都可能是一個不好的做法,在這里,這些塊也被某些人所皺眉,它們可能非常危險並導致難以發現的錯誤(主要是執行順序)。

在兩個示例中,您試圖實現兩個完全不同的目標。

在第一個示例中,您在main方法內部聲明了ArrayList ,因此列表的范圍就是該方法。 封閉的類與該ArrayList完全沒有關系。

在第二個嘗試創建一個數據成員稱為exams在班里InvokeMethod 這意味着該類的每個實例將有其自己的列表。

元素的添加不起作用,因為“方法外”只能進行聲明和初始化。 要解決此問題,可以使用初始化塊

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) {

    }   
}

注意:您還可以通過InvokeMethod類的實例從main方法檢索此列表:

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]

這是因為“您是從函數/方法外部調用它的”

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

上面的行表示您將其聲明為Object的屬性。 這意味着您只能在方法內部訪問它。

如果您要將以下內容放入主目錄

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

盡管您在方法外聲明了“檢查”,但這應該可以正常工作。

根據Java語言規范 ,類主體聲明具有實例初始化器,但沒有方法調用。 因此,在您的示例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
    ;       

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM