2016-09-20 4 views
6

이것은 정말 기본적인 질문 일지 모르지만 이것은 내 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를 객체와 방법을 외부 객체에 대한 호출을 인스턴스화 라인, 객체가 괜찮 만들어 줄하지만 추가 기능을 이동하면() 개체에 대한 메서드 호출은 허용되지 않습니다. 왜 그런가요?

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

    } 

    } 

감사합니다.

+0

[? 초기화 블록은 무엇 (http://stackoverflow.com/questions/3987428/what-is -an-initialization-block) – blackpen

답변

3

단순히 메소드 외부에서 코드를 수행 할 수 없습니다. 이것을 원한다면 이니셜 라이저 블록이나 정적 블록이 필요합니다.

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

이제이 블록은 인스턴스를 만들 때 실행됩니다. 변수가 정적 인 경우 해당 블록을 정적으로 만들 수 있습니다 (블록 앞에 static 만 추가하면됩니다). 정적 블록은 클래스가 초기화 될 때 실행됩니다. 이러한 블록은 채워진 정적 목록/맵이 필요할 때 매우 편리 할 수 ​​있습니다. 물론 프로그래밍에 편리한 모든 것은 나쁜 습관 일 것이고 여기 같은 블록은 어떤 사람들에 의해 눈살을 찌푸리게되며 매우 위험 할 수 있으며 (대부분 실행 순서에 관한) 찾기 힘든 버그로 이어질 수 있습니다. "당신이 기능/방법 외부에서 호출하고"있기 때문이다

+0

철저한 답장을 보내 주셔서 감사합니다 (특히 Whatzs). – soti84

0

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

행 위는 객체의 속성으로 그것을 선언하고 의미합니다. 즉, 메서드 내에서만 액세스 할 수 있습니다.

당신이 다음을 배치 할 거라면 자신의 메인

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

당신이 방법 밖에 "시험"을 선언하지만,이, 그냥 잘 작동합니다.

1

두 가지 예에서 완전히 다른 두 가지 작업을 수행하려고합니다.

첫 번째 예에서는 main 메서드 내에 ArrayList을 선언하므로 목록의 범위는이 방법 일뿐입니다. 동봉 된 클래스는 해당 ArrayList과 전혀 관련이 없습니다.

InvokeMethod 클래스에 exams이라는 데이터 멤버를 만들려고합니다. 즉,이 클래스의 모든 인스턴스에는 자체 목록이 있습니다.

"메서드 중"선언 및 초기화 만 수행 될 수 있기 때문에 요소를 추가 할 수 없습니다.

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

    } 
} 

참고 :이 문제를 해결하려면, 당신은 initialization block을 사용할 수 있습니다 또한 인스턴스를 통해 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] 
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 
    ;  
관련 문제