[완료] 자바에서 클래스의 맴버 변수 생성(초기화) 관련 문법 혹은 익명 내부 클래스 초기화...
글쓴이: jeongheumjo / 작성시간: 화, 2011/02/01 - 1:30오전
아래 코드에서 잘 모르겠는 부분이 있어서 이곳에 문의합니다.
아래 코드에서는 익명클래스가 사용되고 있습니다. 그런데 그 익명클래스의 인스턴스가 만들어지는 곳이 어느 메소드 내부가 아니고 그냥 클래스의 몸체 입니다. 바로 이 부분입니다.
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(); } } }
Forums:
자문자답합니다
제가 C++ 문법만 아는 상태에서 자바 코드를 보니 이런 의문이 들었었습니다.
자바 문법을 공부하면 다 설명이 있었습니다.
익명클래스, 내부클래스, 생성자의 용법과 ... 모두 C++ 과 차이가 있었습니다만,
아직도 책에서 찾지 못한 것은 인스턴스 변수를 클래스 바디에서 초기화하는 것입니다.
위 코드에서 보니 생성자가 호출되기도 전에 초기화가 되었더군요..
출력 결과는
3
5
이니까요...
이런 초기화 문법도 C++ 에는 없는 것이죠.
자바 책의 어디에 이 설명이 있는지는 아직 못찾았지만. 살다보면 알게 되리라 생각합니다.
혼자 공부해보면 될 것을 괜히 공개 개시판에 질문을 올렸던 것 같습니다.
앞으로 이런 질문은 자제해야겠습니다.
모두 즐거운 명절 보내시길 바랍니다.
그냥 스펙 문서 보세요.
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.2
C++에 비하면 대부분의 언어가 스펙 문서 양이 얼마 안됩니다.
안녕하세요?
제 질문에 답변을 여러번 해주셔서 이제는 낮이 익은 느낌입니다.
항상 고맙습니다. 저는 너무 지식이 얕은데 이곳에서 네오코인 님과 같은 분들께 많이 배웁니다.
프로그램 언어가 스팩으로 정의되어있다 라는 것도 사실 잘 와닿는 얘기는 아니었습니다. C 나 C++도 표준이 있는 것을 알지만 표준 문서를 직접 본 적은 없네요.. 자바도 물론이구요...
문법의 엄밀한 정의는 아마도 표준에서 확인하는 것이 가장 정확하겠죠? 하지만 저는 아직은 쉽게 설명해놓은 한글 기술서적을 찾아보게 됩니다.
자바와 디자인 패턴에 관해 요즘 헤드퍼스트 시리즈로 공부중입니다.
수준이 딱 저에게 맞는 것 같아서 좋습니다.
앞으로는 스펙문서도 좀 찾아봐야겠어요. 알려주신 선의 문서를 찾아봐야겠습니다.
감사합니다.
.
원문 그대로 옮기는게 쓸데없는 일인것 같아서 정확한 답변에 해당하는 스펙 문서 링크를 걸어 두었는데, 제가 전달이 부족했나 봅니다.
약간 죄송한 느낌으로, 원문을 옮깁니다. 문서에 이렇게 나와 있습니다.
말씀하신 부분에 대해서 매 생성시 초기화한다고 되어 있습니다.
가입 년수에 비해 너무 겸손하시네요.
이런 언어 사항에 대한 질문에 스펙을 이야기하는 건 대부분의 언어 스펙이 언어 학습에 확실한 기준이고, 이미 수년간의 치열한 논쟁의 결과물이기 때문입니다. 요즘 말로, 언어 질문 종결자랄까요.
그리고 kldp가 java를 주로 하시는 분들이 질답에 관심 멀어져서, (저도 요즘은 java하지 않습니다.) 답변이 별로 없는듯 하네요. (과거, 글들을 기억하면 전문가 분들은 많습니다. ;;)
대안을 말씀드리면, 안드로이드 코드 인듯한데요. 안드로이드 진입하시는 분들이 안드로이드펍 같은 곳에 많이 모이는 것 같네요. 그곳에 올리시면 손쉽게 도움주고 받을수 있을 것 같습니다.
^^
언어질문에 대한 종결자 맞네요 ^^;
정말 자세하게 설명해주셔서 제가 죄송할 정도예요..
제가 가입기간은 길지만 요즘들어서야 kldp에 자주 와보게 됐습니다.
그전에는 kldp가 특별한지 몰랐는데 요즘에서야 kldp 는 좀 특별하구나 하고 많이 느끼고 자주 들어와 보는 중입니다.
배울 수 있는 점도 많고 네오코인님처럼 자세하게 설명해주시는 분들도 많더라구요..
이곳은 리눅스 관련 주제가 메인인데 저는 컴퓨터에 관한 모든 것을 여기서 해답을 찾곤 하네요... 찾으면 이곳에 답이 있기도 하구요.. 요즘 리눅스도 더 많이 사용하고 있기도 합니다.
설 잘 세세요..
C, C++와 Java, C# spec은 느낌이 많이 다릅니다.
C, C++ 표준은 위원회에서 만든 느낌이 많이 들고, 용어해석에서 다른 견해가 없도록 엄밀하게 하기 위해 새로운 용어라고 생각되는 느낌의 용어도 많이 보입니다.
Java spec은 읽기 어렵지 않고, C# spec은 언어 입문서에 가깝다 할 정도더군요. 이렇게 독특한 것들에 대해서 혼자 공부할려면 표준, spec을 찾아보는게 좋습니다.
댓글 달기