Java에서 중괄호는 그 자체로 무엇을 의미합니까?


79

두 가지 방법으로 중괄호를 사용하는 Java 코드가 있습니다.

// Curly braces attached to an 'if' statement:
if(node.getId() != null)
{
    node.getId().apply(this);
}

// Curly braces by themselves:
{
    List<PExp> copy = new ArrayList<PExp>(node.getArgs());
    for(PExp e : copy)
    {
        e.apply(this);
    }
}
outAMethodExp(node);

첫 번째 if문 다음에 나오는 독립형 중괄호 는 무엇을 의미합니까?

답변:


120

추가 중괄호의 유일한 목적은 범위 제한을 제공하는 것입니다. 는 List<PExp> copy해당 중괄호 내에 만 존재하며 그 밖의 범위는 없습니다.

이것이 생성 된 코드 인 경우 코드 생성기가이 작업을 수행하므로 a를 몇 번 삽입했는지에 대해 걱정할 필요 List<PExp> copy없이이 코드 조각이있는 경우 변수 이름을 바꿀 수있는 것에 대해 걱정할 필요없이 일부 코드를 삽입 할 수 있다고 가정합니다. 동일한 메서드에 두 번 이상 삽입됩니다.


9
이 경우 추가 "이점"은 반품 copy전에 가비지 수집 이 가능하다는 것 outAMethodExp()입니다. 장기 실행 또는 메모리 집약적 인 호출 인 경우 도움이 될 수 있습니다. 별도의 메서드로 리팩토링하는 것이 일반적으로이 구문을 이용하는 것보다 훨씬 더 명확하고 명확하기 때문에 "이점"을 따옴표로 묶었습니다.
dimo414

1
실제로 변수 범위 지정은 가비지 수집에 영향을 주지 않습니다 . 내가 아는 모든 최신 JVM에서 JIT는 중괄호와 같은 범위 지정 구조의 존재 여부에 관계없이 객체가 GC에 적합한 지 결정할 수 있습니다.
Daniel Pryden

27

두 번째로 matt b가 작성한 내용을 두 번째로 추가하겠습니다. 익명 중괄호의 또 다른 용도는 익명 클래스에서 암시 적 생성자를 선언하는 것입니다. 예를 들면 :

  List<String> names = new ArrayList<String>() {
    // I want to initialize this ArrayList instace in-line,
    // but I can't define a constructor for an anonymous class:
      {
        add("Adam");
        add("Eve");
      }

  };

일부 단위 테스트 프레임 워크는이 구문을 다른 수준으로 끌어 올려 완전히 컴파일 할 수없는 멋진 일을 허용합니다. 낯설어 보이기 때문에 나도 그렇게 큰 팬은 아니지만,이 사용을 통해 어떤 일이 벌어지고 있는지 적어도 인식하는 것은 가치가 있습니다.


죄송합니다.이 코드를 이해할 수 없습니다. 클래스 또는 함수를 "추가"합니다. 함수 인 경우 : 어떤 클래스에 속합니까? 이 경우 ArrayList가 대리자 형식을 허용합니까?
Peter Mortensen

7
"추가"는 함수입니다. 중괄호 안의 내용은 생성자 전에 호출되어 예비 초기화를 수행합니다. 당신은 체크 아웃 할 수 c2.com/cgi/wiki?DoubleBraceInitialization을 이상.
Zaven Nahapetyan 2010

1
기술적으로 생성자가 먼저 호출되고 인스턴스 초기화 블록이 super(...).
Oli

8

범위 제한 답변에 동의하지만 한 가지 추가하겠습니다.

때로는 코드 섹션을 접는 것을 좋아하고 자동으로 중괄호를 접는 편집기가있는 사람들의 코드에서 이와 같은 구조를 볼 수 있습니다. 그들은 일반적으로 접히는 함수, 클래스, 루프 등에 속하지 않는 논리 섹션에서 코드를 접는 데 사용합니다.


4

누군가가 else 문을 잊었다 고 생각합니다.

추가 블록 범위를 만드는 데 신경을 쓸 이유가 거의 없습니다. 이 경우와 대부분의 경우, 누군가 영리한 일을하고있는 것보다 제어문을 입력하는 것을 잊었을 가능성이 훨씬 더 높습니다.


2
나는 단순히 일어날 수 있고 일어났기 때문에 당신에게 투표하는 것입니다. 그리고 Occam은 당신이 투표하지 않았기 때문에 그의 무덤에서 굴러 가고 있습니다. :)
willasaywhat

1
SableCC에 의해 생성됩니다. 나는 그들이 다른 것을 잊지 않았다 5 $ 내기
Pavel Feldman

추가 중괄호는 블록이 새로운 메서드를 보증 할만큼 충분히 복잡하지 않은 동일한 지점에 몇 개의 유사한 코드 블록을 모두 유지하려는 긴 메서드에서 전역 변수가 사용자에게 표시되는 것을 방지하는 데 유용합니다.
jayunit100 2011

나는 대학에서 자바 코스워크를 표시하고 이것이 실제로 종종 코드에서 발견되는 정확한 이유임을 알 수 있습니다. 사람들을 다시 팩터링 할 때 때로 잘라내거나 붙여 넣은 다음 잘못된 수의 중괄호를 보게됩니다. 하나만 추가하면됩니다. 그런 이유로 나는 이것을 투표하고 있습니다. 항상 else 문은 아니지만 종종 단순한 실수입니다.
ThePerson 2013 년

-1 표는 참여하지 않았어야한다는 의미이기 때문에 찬성했습니다. 몰랐을 수도 있지만 노력을 기울였습니다. 나는 모든 사람을위한 트로피가 아니지만 "감사합니다"는 도움을 주려는 사람들에게하는 말입니다. (+1 == 감사합니다).
user426364

2

그들은 내부 범위를 만듭니다. 이 중괄호 안에 선언 된 변수는 그 밖에 보이지 않습니다. 이것은 C / C ++에도 적용됩니다.


1

중괄호는 switch / case 문의 범위를 줄이는데도 유용합니다.

switch(foo) {
  case BAR:
     int i = ...
     ...
  case BAZ:
     int i = ... // error, "i" already defined in scope
}

하지만 당신은 쓸 수 있습니다

switch(foo) {
  case BAR:{
     int i = ...
     ...
  }
  case BAZ:{
     int i = ... // OK
  }
}

1

또한 초기화 블록 에도 사용됩니다 .


이것은 생성자 외부의 정적 클래스 초기화에만 해당된다는 점을 언급 할 가치가 있습니다. OP 코드 조각은 메서드 블록에 있습니다 (가능한 위치에서만 가능).
mmoore

그것은로 시작하는 경우는 초기화 블록은 정적 클래스 초기화위한 static달리 그의 인스턴스 초기화 블록.
가브리엘

진정한 이야기. 설명해 주셔서 감사합니다.
mmoore 2013-03-15

0

이 범위에 선언 된 모든 항목이 중괄호 외부에 표시되지 않음을 의미하는 새 범위를 정의합니다.


0

흥미로운 점 : 중괄호는 실제로 선언문 클래스를 활성화합니다.

이것은 불법입니다. if(a) int f;

그러나 이것은 합법적입니다. if(a) { int f; }


정확히이 코드는 쓸모가 없으며 중괄호 외부에서 f를 볼 수 없습니다. 그리고 그것을 사용하려면 동일한 범위 내에서 선언하고 사용해야합니다. 따라서 둘 이상의 문이 필요하므로 중괄호가 필요합니다.
Pavel Feldman

그것이 내가 언급하고있는 컴파일러 검사의 요점입니다. "암시 적 범위"(중괄호가없는 각 한 줄짜리 줄을 중괄호가없는 것으로 간주 함)와 명시 적 범위에 차이가 있다는 것이 흥미 롭습니다. 컴파일러가 차이를 만들 것이라는 사실을 잊기 쉽습니다.
Hugo

if (userWantsTocInReport) {new Toc (report};}? 이것이 이상적인 작성 방법이라고 말하는 것은 아니지만 어떤 이유로 든 누군가가 선택할 수있는 가능성입니다.
user625488


0

범위 가져 오기, 사본 은 외부에 표시되지 않으므로 나중에 동일한 이름으로 다른 변수를 선언 할 수 있습니다. 그리고 해당 범위를 종료 한 직후 가비지 수집기에 의해 수집 될 수 있습니다. 이 경우 복사 는 임시 변수 역할을하므로 좋은 예입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.