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.