자바(안드로이드) 코드 문의

jeongheumjo의 이미지

오늘 자바프로그램 소스코드를 보다가 모르는 문법을 발견해서 여기에 질문을 올려봅니다.

코드는 아래와 같습니다. 제가 궁금한 것은 mClickPlay, mClickStop, mComplete, mSizeChange 라는 멤버 변수들의 선언과 초기화가 어떻게 이루어지는 것인가 하는 것입니다.

public class mm_PlayVideo extends Activity implements SurfaceHolder.Callback {

public void onCreate(Bundle savedInstanceState) {
...........................
}

Button.OnClickListener mClickPlay = new View.OnClickListener() { // 여기 !!!
...........................
};

Button.OnClickListener mClickStop = new View.OnClickListener() { // 여기 !!!
...........................
};

public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
}

public void surfaceDestroyed(SurfaceHolder surfaceholder) {
}

public void surfaceCreated(SurfaceHolder holder) {
...........................
}

MediaPlayer.OnCompletionListener mComplete = // 여기 !!!
new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
mPlayBtn.setText("Play");
}
};

MediaPlayer.OnVideoSizeChangedListener mSizeChange = // 여기 !!!
new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
}
};

protected void onDestroy() {
...........................
}
}

보시면 대입연산자로 값을 대입하고 있습니다. 그런데 이곳은 클래스의 몸체 입니다. 어느 메소드의 몸체가 아니고요...
자바에서는 이렇게도 하나본데 C++에서는 이렇게 할 수 없죠.
생성자도 아니고 어느 메소드의 몸체(스택)도 아닌 클래스에서 이렇게 선언하고 초기화를 하면 어느 순간에 초기화가 되는 것인가요?

정말 궁금합니다.

참고로 위의 소스코드는 유명한 김상형씨의 안드로이드 강좌 웹사이트에서 퍼왔습니다.

http://www.winapi.co.kr/android/

추가강좌 > 멀티미디어 > 비디오

감사합니다.

neocoin의 이미지

http://developer.android.com/guide/topics/fundamentals.html#actlife

Activity 의 life cycle 을 보시면 알수 있습니다. 안드로이드 문서 중 Framework Topic의 가장 첫 문서입니다.
안드로이드 프레임웍에서 초기화하고 생성합니다.

안드로이드를 시작하실때, 이 문서를 읽으면 기본 개념을 알 수 있습니다.

ps.
Android 가 Java 5 문법을 지원하기는 하지만 Java란 단어를 안쓰죠. jdk조차 오라클 것을 피했습니다.
라이선스 문제를 위해서라도 On2 구입하듯이 질러서 sun을 구입했어야 하는데, 좀 아쉬운 부분입니다.

오라클과 쓸때없는 씨름을 안했으면 하네요.

jeongheumjo의 이미지

답변 정말 감사드립니다.
Java5를 지원하지만 VM 이 다르고 Java5 이외의 문법이 더 추가된 것이라고 보면 될까요?
예를 들어 마이크로소프트의 비주얼스튜디오와 윈도우즈에서 표준 C/C++ 을 지원하지만 마사만의 데이타 타입이라든가 예외처리 문법을 가지고 있는 것 처럼요?

그리고 그렇다면 제가 문의드린 것은 Java5에는 없는 것인가보군요? <-- 이 부분은 제가 알려주신 참고자료를 통해 알아보겠습니다. 방금 찾았네요. 설명이 잘 되있군요.. ^^;

감사합니다.

neocoin의 이미지

ps에 표현 틀린 부분

Java 5 문법이라고 했는데, 이런건 없죠.

Android는 Java Language Specification Fourth Edition (이하 JLS)까지 잘 지원하는거 같네요.

Android에 추가된 문법은 없습니다. 모든걸 Android Framework 로 녹였습니다.
있다면 다른 컴파일러들의 문법 체크도 통과 못합니다.(Eclipse IDE를 못쓰죠.)

여담으로, Java 5이후 JLS가 변경된건 아직 없습니다. Java 7이 나올때 문법적 변화 사항때문에 아마 JLS Fifth Edition이 나올꺼 같네요.

----
동문서답하고 있는 부분.

좀 느낌이 이상했는데, 문의 하신 코드 예제를 잘 안 읽어본게 잘못된 답변의 원인입니다. 전체 소스를 보고는 Activity life cycle 을 의미하는줄 알았네요. ;;

예전 부터 JLS의 일부입니다. AWT 시절부터 이를 통해 구현 예제를 보였습니다. 이미 찾으셨겠지만, 용어는 Anonymous Class 입니다. See Also [Expressions](http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#252986)

말씀 중 아래의 생략된 부분 때문에 착각해버렸네요.

  Button.OnClickListener mClickPlay = new View.OnClickListener() { // 여기 !!!
  ...........................  // 이 부분이 이걸 알아보는데 가장 중요한 부분입니다.
  };

[anonymous classes : Java Glossary](http://mindprod.com/jgloss/anonymousclasses.html) 에 예제가 잘나와 있네요.

문법 모호하면 JLS 읽어보세요. 생각보다 읽을 분량이 분량이 많지 않습니다. (C/C++ 호환 문법을 다 뛰어 넘어 버리면 되니까요 ;;)

jeongheumjo의 이미지

아직 알려주신 래퍼런스들을 다 읽어보지 못해서 답글 달기 좀 이른 것 같습니다만,
살짝만 봤을 때는 C++의 임시객체와 비슷한 것 같아요...
그런데 제가 정말 궁금한 것은 그 anonymous class 의 객체 생성이 "언제" 이루어지는가 하는 것입니다.
알려주신 래퍼런스의 예제를 보면 그 생성은 어느 메소드 내에서 이루어지고 있거든요.
제가 올려놓은 코드에서는 클래스의 선언부에서 클래스의 맴버 변수를 선언하는 곳에 new 연산자로 객체를 생성하고 있습니다.
이 부분은 어느 메소드 내부가 아니라서 저는 그 생성이 어느 문맥에서 이루어지는지가 궁금한 것이었어요...

보통은 생성자를 이용하는데 이 부분은 생성자가 아닌데 말이죠...
알려주신 래퍼런스을 좀 더 읽어보겠습니다. 감사합니다. ^^;

neocoin의 이미지

C++ 을 하셔서 그런지 그런 관점에서 관심이 많으신거 같군요.

지금 말씀중에 class는 '클래스'로 object(instance)는 객체로 지칭하신다고 이해합니다. 저는 이하 모호함을 피하기위해 class, instance로 이야기 하겠습니다.

말씀하시는 궁금증은 컴파일해서 결과 파일들을 보면 확인할 수 있습니다. 일단 다음의 코드를 컴파일 합니다.

Main.java

interface A{
  void hello();
}
public class Main {

  public static void main(String[] args) {
    A a = new A(){
      @Override
      public void hello() {
        System.out.println("hello");
      }      
    };
    a.hello();
    A b = new A(){
        @Override
        public void hello() {
          System.out.println("hello");
      }      
    };
    
  }
}

그럼 다음의 코드가 컴파일되서 튀어 나옵니다.

A.class -> A interface
Main$1.class -> anonymous class
Main$2.class -> anonymous class
Main.class -> Main class

이런 식입니다. 이렇게 만들어진 class를 대상으로 runtime에 instance가 생성이 되는거죠. $ 문자와 첫글자로 숫자를 java class name으로 쓸 수 없기 때문에 저렇게 컴파일러는 생성합니다. 룰을 어디서 본거 같은데 기억이 잘 안나서 모르겠네요. 이들을 javap로 디스 어셈 할수 있는데, anonymous class 는 그 대상이 안됩니다. 이름이 없어서요.

자세한 사항은 VM Spec The class File Format 을 참고하시면 되겠지만 JVM 만들일이 없으니 참고하실 필요는 없지 않을까 싶네요. ;;


그리고 C++ 의 임시 객체(Temporary Object)와는 다릅니다. 두 대상의 개념 차이가 커서 좀 말하기가 힘드네요. Java가 레퍼런스로 구성된 이상 '임시 객체'는 존재할수가 없는 구조잖아요. C++로 코딩할때 가장 신경쓰이는 부분 중 하나죠.

여담으로, 덕분에 C++ 0x 에서 Rvalue reference 에 굉장히 심혈을 기울인 흔적들이 보입니다. 좋아지는 세상인데, 스팩은 더 두꺼워지고 신경쓸건 많아지는 것 같네요.


ps. 아.. 역시 다른 반드시 일이 있어서 집에 있는 시간에는 이런 질답에 왜이리 집중이 잘되는지 원..

jeongheumjo의 이미지

어느분들은 퉁명스럽게 쏘아주시는 분들도 계신데요...
저는 게시판에 질문을 올리고 관련 내용을 모른채 해당 코드를 수정하는 작업을 진행중에 있습니다.
위의 anonymous class 와 같은 것들을 잘 모르면서도 마구 만들어서 테스트 해보고 있습니다. ^^;

그런데 이번 설명에서도 anonymous class 를 new 로 생성하는 부분이 main 이라는 메소드에 있군요... TT
아마 어느 메소드에 내에 있든 아니면 메소드 밖에 있든 별로 중요하지 않겠죠? 그리고 제 문제에서는 @Override 라는 키워드가 없지만 그것도 별로 중요하지 않구요...

이제는 답변 안해주셔도 좋습니다. ^^;
제가 너무 계속 물어보고 있는 것 같아서 죄송하네요...
제가 알아볼 일인 것 같습니다.

알려주신 래퍼런스들도 꼭 참고 하겠습니다.
감사합니다.

neocoin의 이미지

이런 모습을 말씀하신거 같네요. Java 언어 상에 특이점 중 하나인데... 아래와 같이 구성하면

interface A {
  void hello();
}

public class Main {
  A a = new A() {
    @Override
    public void hello() {
      System.out.println("hello");
    }
  };

  public static void main(String[] args) {
    A a = new A() {
      @Override
      public void hello() {
        System.out.println("hello");
      }
    };
    a.hello();
    A b = new A() {
      @Override
      public void hello() {
        System.out.println("hello");
      }
    };
    Main m = new Main();
    m.a.hello();
  }
}

이렇게 컴파일 결과가 이렇게 나오죠. anonymous class 를 사용한 만큼 만들어 집니다.

A.class
Main$1.class
Main$2.class
Main$3.class
Main.class

적다 보니, 생각나네요. anonymous class 는 C/C++로 비교하자면 stl에서 functor 역할이나, 함수 포인터 역할로 많이 쓰입니다. 로직을 외부에서 구현할때 (예- 정렬 규칙) 인터페이스 구현을 선언해서 파일까지 빼는 것 보다 단축해서 사용하죠.

보여주신 예제도 자세 보시면 이벤트 핸들링을 위한 로직이 담겨 있을 겁니다. 함수 포인터 개념을 제공하지 않는 Java에서 쓸수 있는 일반적인 방법입니다.

@Override 부분의 문법은 annotation 이라고 부르며 class 파일에 메타 정보를 담기위한 용도입니다. 메타 정보라서 구지 필요하지는 않습니다. 안드로이드 플랫폼은 annotation을 설정으로 쓰지를 않더군요.


답변자들의 첫 반응이 퉁명스럽다고 고민되시면,

How To Ask Questions The Smart Way

이거 좋습니다. 영어 원문은 버전이 더 올라갔는데, 별 상관없습니다.

jeongheumjo의 이미지

또 친절한 설명을 해주셨네요 ^^;
오늘 제가 님에게 감사를 몇번을 드리는지 모르겠습니다.
정말 감사합니다.
남아있던 의문점까지 해결이 되었습니다 *^^*

C++ 에서는 비슷한 예로 템플릿이 있는 것 같아요.. functor에 대해서는 자세히 모르지만요 맞는 말씀 같습니다. 템플릿도 클래스가 만들어지는 시점이 빌드할 때이죠. 이 문제의 자바의 경우에 그 역할을 new 가 하는 것 같습니다. 계속 의문을 가지고 있었던 것이 new는 연산자라는 관념 때문이었던 것 같아요.

"이름없는 클래스" 잘 알아두겠습니다.

감사합니다.

neocoin의 이미지

제가 괜히 다른 개념을 꺼냈네요. 저는 쓰이는 용도 관점에서 비슷함을 거론한거지, 컴파일 관점에서 비슷함을 거론한게 아닙니다. 문법이나 구현상으로 C++에 비슷한게 없습니다. 그래서 자주 쓰이는 용도를 말씀드린겁니다.

어차피 시간이 지나가면 다 아시게 되겠지만... 첨언합니다.

anonymous class 는 한서에서 '익명 클래스'라고 번역됩니다. 키워드르 저렇게 잡고 검색하시면 됩니다.

구현체(컴파일 관점)에서 이해하시면 Template 유사하게 생각할 수 있을 것 같습니다. 하지만, 각 언어의 개념의 유사점은, 개념이나 문법이 언어에서 역할을 비교하는게 좀 더 이해를 돕는다고 생각합니다.


Template 의 목적은 서로 다른 타입에 대한 소스 중복을 방지하고, 컴파일 타임에 에러 검출을 할수 있는 문법인데, 이런 목적은 JLS 4th에 이르러 Generics 라는 형태로 유사한 문법이 정의되었습니다.

예를들어 다음과 같습니다.

List<String> l = new ArrayList<String>();
l.add("abc");
String b = l.get(0);

std::vector 와 매우 유사하죠. 용도도 비슷합니다. 컴파일 타임에 collection에 의도한 type 체크를 하겠다는 거죠.

하지만 Generics의 구현은 C++의 Template과 매우 다릅니다. 컴파일은 위의 코드를 아래 형태로 '번역'하는 수준입니다. 그냥 컴파일 타임에 type check 정도만 머물렀습니다. (성능이 향상된다거나 이런거 없습니다.)

이게 과거 코드입니다. - Java 1.4 때

List l = new ArrayList();
l.add("add");
String b = (String)l.get(0);

Java를 학습하면서 C/C++ 과 비교하는건 편할지 모르겠지만, 곳곳에 지뢰가 있네요. 저도 예전에 그런 부분에서 고심을 했던거 같습니다. 하지만 그냥 원래 키워드 자체의 의미를 받아들이는 편이 수월하실 것 같네요.

ps. Ruby 맛을 봤더니, 전 JLS 4th가 매우 기대되네요. ;;

neocoin의 이미지

..

jeongheumjo의 이미지

네 지금은 제가 모든 내용을 이해하기 어려운 것 같습니다.
자바에 대해서 좀 공부를 해봐야 그리고 익명클래스에 대해서도 공부를 해봐야 할 것 같아요..
알려주신 내용 참고해서 잘 알아보겠습니다.

C++의 프레임을 버리고 새로운 마음으로 공부해야되겠어요 ^^;

감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.