[완료] 자바에서 클래스의 맴버 변수 생성(초기화) 관련 문법 혹은 익명 내부 클래스 초기화...

jeongheumjo의 이미지

아래 코드에서 잘 모르겠는 부분이 있어서 이곳에 문의합니다.
아래 코드에서는 익명클래스가 사용되고 있습니다. 그런데 그 익명클래스의 인스턴스가 만들어지는 곳이 어느 메소드 내부가 아니고 그냥 클래스의 몸체 입니다. 바로 이 부분입니다.

public class mm_PlayVideo extends Activity implements SurfaceHolder.Callback {
     Button.OnClickListener mClickPlay = new View.OnClickListener() {
     ............................
     };
}

자바 책을 찾아봐도 익명 클래스나 내부클래스에 대한 설명은 있습니다. 그런데 모든 예제가 익명내부 클래스는 메소드 내에서 new 로 생성합니다. 그런데 이 예제에서는 어느 메소드 내부가 아니예요... 그냥 외부 클래스의 몸체입니다.
그러면 그 익명 내부 클래스가 어느 순간 생성되게 되죠?

익명 내부 클래스가 아닌 일반 int 타입 등의 변수는 어떨까 시험해 봤습니다.
아래의 코드는 자바에서는 에러가 나지 않는군요!!!!

class Test {
     int myVar = 100;
}

C++(비주얼스튜디오) 에서는 아래와 같은 에러가 발생합니다.

"only static const integral data members can be initialized within a class"

그러고 보면, 이 문제는 익명 내부 클래스의 문제가 아니라 자바의 클래스 멤버 변수의 초기화 문법과 관련된 문제 같습니다.

이 부분에 대해 정확히 알고자 한다면 자바 책에서 어느 부분을 봐야 할까요? 생성자 부분일까요?

아래는 제가 궁금해했던 전체 원본 소스 입니다.
김상형씨의 winapi.co.kr 에 있는 소스인데 제가 허락도 없이 인용했네요... 괜찮겠죠? 이정도는...

감사합니다.

public class mm_PlayVideo extends Activity implements SurfaceHolder.Callback {
     private SurfaceView mPreview;
     private SurfaceHolder mHolder;
     MediaPlayer mPlayer;
     Button mPlayBtn;
 
     public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.mm_playvideo);
 
          mPreview = (SurfaceView) findViewById(R.id.surface);
          mHolder = mPreview.getHolder();
          mHolder.addCallback(this);
          mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
          mPlayBtn = (Button)findViewById(R.id.play);
          mPlayBtn.setOnClickListener(mClickPlay);
          findViewById(R.id.stop).setOnClickListener(mClickStop);
     }
 
     Button.OnClickListener mClickPlay = new View.OnClickListener() {
          public void onClick(View v) {
              if (mPlayer.isPlaying() == false) {
                   mPlayer.start();
                   mPlayBtn.setText("Pause");
              } else {
                   mPlayer.pause();
                   mPlayBtn.setText("Play");
              }
          }
     };
 
     Button.OnClickListener mClickStop = new View.OnClickListener() {
          public void onClick(View v) {
              mPlayer.stop();
              try {
                   mPlayer.prepare();
              } catch (Exception e) {;}
          }
     };
 
     public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
     }
 
     public void surfaceDestroyed(SurfaceHolder surfaceholder) {
     }
 
     public void surfaceCreated(SurfaceHolder holder) {
          if (mPlayer == null) {
              mPlayer = new MediaPlayer();
          } else {
              mPlayer.reset();
          }
          try {
              mPlayer.setDataSource("/sdcard/testvideo.mp4");
              mPlayer.setDisplay(holder);
              mPlayer.prepare();
              mPlayer.setOnCompletionListener(mComplete);
              mPlayer.setOnVideoSizeChangedListener(mSizeChange);
          } catch (Exception e) {
              Toast.makeText(mm_PlayVideo.this, "error : " + e.getMessage(),
                        Toast.LENGTH_LONG).show();
          }
     }
 
     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() {
          super.onDestroy();
          if (mPlayer != null) {
              mPlayer.release();
          }
     }
}

jeongheumjo의 이미지

제가 C++ 문법만 아는 상태에서 자바 코드를 보니 이런 의문이 들었었습니다.
자바 문법을 공부하면 다 설명이 있었습니다.
익명클래스, 내부클래스, 생성자의 용법과 ... 모두 C++ 과 차이가 있었습니다만,
아직도 책에서 찾지 못한 것은 인스턴스 변수를 클래스 바디에서 초기화하는 것입니다.

public class Hipo {
 
	int hipoVar = 3;
 
	public Hipo() {
		System.out.println(hipoVar);
		hipoVar = 5;
		System.out.println(hipoVar);
	}
}

위 코드에서 보니 생성자가 호출되기도 전에 초기화가 되었더군요..
출력 결과는
3
5
이니까요...

이런 초기화 문법도 C++ 에는 없는 것이죠.
자바 책의 어디에 이 설명이 있는지는 아직 못찾았지만. 살다보면 알게 되리라 생각합니다.

혼자 공부해보면 될 것을 괜히 공개 개시판에 질문을 올렸던 것 같습니다.
앞으로 이런 질문은 자제해야겠습니다.

모두 즐거운 명절 보내시길 바랍니다.

neocoin의 이미지


http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.2

C++에 비하면 대부분의 언어가 스펙 문서 양이 얼마 안됩니다.

jeongheumjo의 이미지

제 질문에 답변을 여러번 해주셔서 이제는 낮이 익은 느낌입니다.
항상 고맙습니다. 저는 너무 지식이 얕은데 이곳에서 네오코인 님과 같은 분들께 많이 배웁니다.
프로그램 언어가 스팩으로 정의되어있다 라는 것도 사실 잘 와닿는 얘기는 아니었습니다. C 나 C++도 표준이 있는 것을 알지만 표준 문서를 직접 본 적은 없네요.. 자바도 물론이구요...
문법의 엄밀한 정의는 아마도 표준에서 확인하는 것이 가장 정확하겠죠? 하지만 저는 아직은 쉽게 설명해놓은 한글 기술서적을 찾아보게 됩니다.
자바와 디자인 패턴에 관해 요즘 헤드퍼스트 시리즈로 공부중입니다.
수준이 딱 저에게 맞는 것 같아서 좋습니다.
앞으로는 스펙문서도 좀 찾아봐야겠어요. 알려주신 선의 문서를 찾아봐야겠습니다.
감사합니다.

neocoin의 이미지

원문 그대로 옮기는게 쓸데없는 일인것 같아서 정확한 답변에 해당하는 스펙 문서 링크를 걸어 두었는데, 제가 전달이 부족했나 봅니다.

약간 죄송한 느낌으로, 원문을 옮깁니다. 문서에 이렇게 나와 있습니다.

Thus the example:
 
class Test {
    float f = j;
    static int j = 1;
}
compiles without error; it initializes j to 1 when class Test is initialized,
 and initializes f to the current value of j every time an instance of class Test is created.

말씀하신 부분에 대해서 매 생성시 초기화한다고 되어 있습니다.


가입 년수에 비해 너무 겸손하시네요.

이런 언어 사항에 대한 질문에 스펙을 이야기하는 건 대부분의 언어 스펙이 언어 학습에 확실한 기준이고, 이미 수년간의 치열한 논쟁의 결과물이기 때문입니다. 요즘 말로, 언어 질문 종결자랄까요.

그리고 kldp가 java를 주로 하시는 분들이 질답에 관심 멀어져서, (저도 요즘은 java하지 않습니다.) 답변이 별로 없는듯 하네요. (과거, 글들을 기억하면 전문가 분들은 많습니다. ;;)

대안을 말씀드리면, 안드로이드 코드 인듯한데요. 안드로이드 진입하시는 분들이 안드로이드펍 같은 곳에 많이 모이는 것 같네요. 그곳에 올리시면 손쉽게 도움주고 받을수 있을 것 같습니다.

jeongheumjo의 이미지

언어질문에 대한 종결자 맞네요 ^^;
정말 자세하게 설명해주셔서 제가 죄송할 정도예요..
제가 가입기간은 길지만 요즘들어서야 kldp에 자주 와보게 됐습니다.
그전에는 kldp가 특별한지 몰랐는데 요즘에서야 kldp 는 좀 특별하구나 하고 많이 느끼고 자주 들어와 보는 중입니다.
배울 수 있는 점도 많고 네오코인님처럼 자세하게 설명해주시는 분들도 많더라구요..

이곳은 리눅스 관련 주제가 메인인데 저는 컴퓨터에 관한 모든 것을 여기서 해답을 찾곤 하네요... 찾으면 이곳에 답이 있기도 하구요.. 요즘 리눅스도 더 많이 사용하고 있기도 합니다.

설 잘 세세요..

winner의 이미지

C, C++ 표준은 위원회에서 만든 느낌이 많이 들고, 용어해석에서 다른 견해가 없도록 엄밀하게 하기 위해 새로운 용어라고 생각되는 느낌의 용어도 많이 보입니다.
Java spec은 읽기 어렵지 않고, C# spec은 언어 입문서에 가깝다 할 정도더군요. 이렇게 독특한 것들에 대해서 혼자 공부할려면 표준, spec을 찾아보는게 좋습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.