U E D R , A S I H C RSS

Android/Wallpaper Changer


1. μ„λͺ…


  • 2012λ…„ 4μ›” μ€‘μˆœ κΉ€μ€μ„μ΄ μ˜μ–΄κ³΅λΆ€ν•˜κΈ° μ‹«μ–΄μ„œ λ§Œλ“œλŠ” μ–΄ν”Œ
  • μ•ˆλ“œλ‘œμ΄λ“œ 배경화면이 ν•œκ°œμΈκ²Œ λ„ˆλ¬΄ μ‹«μ–΄μ„œ μ—¬λŸ¬κ°œ 선택후 λ°”κΎΈκ²Œ ν•˜λŠ” μ–΄ν”Œμ„ λ§Œλ“€κ³  μ‹Άμ–΄μ„œ λ§Œλ“€κ²Œλ¨.
    • 근데 λ‚œ λ°°κ²½ν™”λ©΄ 5개인데 -γ……-γ…‹ - ꢌ순의

2. μ œμž‘ κ³Όμ •

  1. μ–΄ν”Œμ— ν•„μš”ν•œ λ°°μšΈκ²ƒ 체크
    • Android의 κΈ°λ³Έ μ–΄ν”Œλ‘œ μž₯μ°©λ˜μ–΄μžˆλŠ” Gallery μ–΄ν”Œλ‘œ Intentλ„˜κΈ΄ν›„ 리슀트 λ‹€μ‹œ λ°›μ•„μ˜€κΈ°.
    • Android의 Wallpaper λ°”κΎΈλŠ” API찾아보기
    • νŠΉμ •μ‹œκ°„λ˜λ©΄ μž‘λ™λ˜κ²Œν•˜λŠ” μ•ŒλžŒκΈ°λŠ₯ 써보기
  2. μ„계 ν›„ 톡합 μ œμž‘
  3. λ””λ²„κ·ΈλΌ ν•˜κ² μ§€

3. μ–΄ν”Œμ— ν•„μš”ν•œ λ°°μšΈκ²ƒ 체크

3.1. Android의 κΈ°λ³Έ μ–΄ν”Œλ‘œ μž₯μ°©λ˜μ–΄μžˆλŠ” Gallery μ–΄ν”Œλ‘œ Intentλ„˜κΈ΄ν›„ 리슀트 λ‹€μ‹œ λ°›μ•„μ˜€κΈ°



   package june.my.testdroid;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;

public class TestdroidActivity extends Activity {

	private static final int SELECT_PICTURE = 1;

	private String selectedImagePath;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        openPhotoLibrary();
               
    }

	private void openPhotoLibrary() {
		//Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		Intent i = new Intent();
		
		i.setType("image/*");
		//i.setType(MediaStore.Images.Media.CONTENT_TYPE);
		i.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(i, "Select Picture"), SELECT_PICTURE);
	}
	
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
	    if (resultCode == RESULT_OK) {
	        if (requestCode == SELECT_PICTURE) {
	            Uri selectedImageUri = data.getData();
	            selectedImagePath = getPath(selectedImageUri);
	        }
	    }
	}

	public String getPath(Uri uri) {
	    String[] projection = { MediaStore.Images.Media.DATA };
	    Cursor cursor = managedQuery(uri, projection, null, null, null);
	    int column_index = cursor
	            .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
	    cursor.moveToFirst();
	    return cursor.getString(column_index);
	}
    
}



3.2. Android의 Wallpaper λ°”κΎΈλŠ” API찾아보기


  • Wallpaperλ°”κΎΈλŠ”λ° Permission ν•„μš”ν•˜λ”λΌ (Androidmenifest.xml파일 μˆ˜μ • μš”ν•¨)
  • WallpaperManager ν΄λž˜μŠ€λΌ ν†΅ν•΄ ν• μˆ˜ μžˆλ”λΌ
  • BitmapFactoryλΌ ν†΅ν•΄ 이λΈμ§€ λ°”κΏ€μˆ˜ μžˆλ”λΌ
  • manager.setBitmap(Bitmap.createScaledBitmap(b, d.getWidth()*4, d.getHeight(), true)); μ™œ * 4냐면 λ‚΄ 폰에 배경화면이 4칸이라 λ‹΅ν•˜κ² λ”λΌ


package june.mywallpaper.com;

import java.io.IOException;

import android.app.Activity;
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MywallpaperActivity extends Activity {
    private static final Button Button = null;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ImageView img1 = (ImageView)findViewById(R.id.imageView1);
        img1.setImageResource(R.raw.wall1);
        img1.setVisibility(View.VISIBLE);
        
        
        Button btn1 = (Button)findViewById(R.id.button1);
        btn1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	Bitmap b = BitmapFactory.decodeStream(getResources().openRawResource(R.raw.wall1));
            	WallpaperManager manager = WallpaperManager.getInstance(MywallpaperActivity.this);
            	final Display d = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
            	try{
               		manager.setBitmap(Bitmap.createScaledBitmap(b, d.getWidth()*4, d.getHeight(), true));
            		Toast.makeText(getApplicationContext(), "λ°°κ²½ν™”λ©΄ 지정 성곡", 1).show();
            	}catch(IOException e){
            		e.printStackTrace();
            		Toast.makeText(getApplicationContext(), "λ°°κ²½ν™”λ©΄ 지정 μ‹€νŒ¨", 1).show();
            	}
            	
            }
        });
    }
}

3.3. νŠΉμ •μ‹œκ°„λ˜λ©΄ μž‘λ™λ˜κ²Œν•˜λŠ” μ•ŒλžŒκΈ°λŠ₯ 써보기


  • μ•ˆλ“œλ‘œμ΄λ“œμ˜ μ„œλΉ„μŠ€λΌ μ΄μš©ν•΄μ„œ κ΅¬ν˜„.
  • ServiceλŠ” μ•ˆλ“œλ‘œμ΄λ“œ Activity와 λ³„λ„λ‘œ κ΅¬ν˜„ν•΄μ•Ό ν•˜λ©° 2.3.3버전 이후 단독 싀행이 λΆˆκ°€λŠ₯ν•˜λ‹€κ³  ν•˜λ‹€.
  • λ˜ν•œ ServiceλŠ” AndroidManifest.xmlνŒŒμΌμ— λ‹Ήμ—°νžˆ 등둝을 ν•΄μ•Όν•œλ‹€. (Applicationνƒ­ -> Service등둝)

  • μ•‘ν‹°λΉ„ν‹° 클래슀

package june.myservice.com;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MyserviceActivity extends Activity {
	 
    ComponentName mService;    // μ‹œμž‘ μ„œλΉ„μŠ€μ˜ 이름
     TextView mTextView;              // μ„œλΉ„μŠ€ μƒνƒœ ν‘œμ‹œ
 
    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         
        mTextView = (TextView)findViewById(R.id.text_view);
         
        Button start = (Button)findViewById(R.id.start_button);
         start.setOnClickListener(new View.OnClickListener(){
             public void onClick(View v) {
                 startHelloService();
             }});
         
        Button stop = (Button)findViewById(R.id.stop_button);
         stop.setOnClickListener(new View.OnClickListener(){
             public void onClick(View v) {
                 stopHelloService();
             }});
     }
 



    // μ„œλΉ„μŠ€ μ‹œμž‘ μš”μ²­
     private void startHelloService() {
         mService = startService(new Intent(this, MyService.class));
         mTextView.append(mService.toShortString()+" started.\n");
     }
 
 
 
    // μ‹€ν–‰ν•œ μ„œλΉ„μŠ€ 쀑지 μš”μ²­
 
    private void stopHelloService() {
         if (mService == null) {
             mTextView.append("No requested service.\n");
             return;
         }
         
        Intent i = new Intent();
         i.setComponent(mService);
         if (stopService(i))
             mTextView.append(mService.toShortString()+" is stopped.\n");
         else
             mTextView.append(mService.toShortString()+" is alrady stopped.\n");
     }
 }
 


  • μ„œλΉ„μŠ€ 클래슀



  package june.myservice.com;

import java.io.IOException;

import android.app.Service;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.Toast;

public class MyService extends Service implements Runnable{

	// μ‹œμž‘ ID
    private int mStartId;
    // μ„œλΉ„μŠ€μ— λŒ€ν•œ μŠ€λ ˆλ“œμ— μ—°κ²°λœ Handler. 타이머 μ΄μš©ν•œ 반볡 μ²˜λ¦¬μ‹œ μ‚¬μš©.
    private Handler mHandler;
    // μ„œλΉ„μŠ€ λ™μž‘μ—¬λΆ€ flag
    private boolean mRunning;
    // 타이머 μ„μ • (2초)
    private static final int TIMER_PERIOD = 2 * 1000; 
    private static final int COUNT = 10;
    private int mCounter;


   // μ„œλΉ„μŠ€λΌ μƒμ„±ν•  λ•Œ 호좜
    public void onCreate() {
        Log.e("MyService", "Service Created.");
        super.onCreate();
        mHandler = new Handler();
        mRunning = false;
    }


   // μ„œλΉ„μŠ€ μ‹œμž‘ν•  λ•Œ 호좜. backgroundμ—μ„œμ˜ μ²˜λ¦¬κ°€ μ‹œμž‘λ¨.
    // startId : μ„œλΉ„μŠ€ μ‹œμž‘μš”κ΅¬ id. stopSelfμ—μ„œ μ’…λ£Œν•  λ•Œ μ‚¬μš©. 

    //onStartλŠ” μ—¬λŸ¬λ²ˆ 호좜될 수 있기 λ•Œλ¬Έμ— μ‹λ³„μžλ‘œ μ‚¬μš©.

   public void onStart(Intent intent, int startId) {
        Log.e("MyService", "Service startId = " + startId);
        super.onStart(intent, startId);
        mStartId = startId;
        mCounter = COUNT;

       // λ™μž‘μ€‘μ΄ μ•„λ‹ˆλ©΄ run λ©”μ†Œλ“œλΌ μΌμ • μ‹œκ°„ 후에 μ‹œμž‘
        if (!mRunning) {
              // this : μ„œλΉ„μŠ€ 처리의 본체인 run λ©”μ†Œλ“œ. Runnable μΈν„°νŽ˜μ΄μŠ€λΌ κ΅¬ν˜„ ν•„μš”.
              // postDelayed : μΌμ •μ‹œκ°„λ§ˆλ‹€ λ©”μ†Œλ“œ 호좜
              mHandler.postDelayed(this, TIMER_PERIOD);
              mRunning = true;
        }
    }



   // μ„œλΉ„μŠ€μ˜ μ’…λ£Œμ‹œ 호좜
    public void onDestroy() {
        // onDestroyκ°€ ν˜ΈμΆœλ˜μ–΄ μ„œλΉ„μŠ€κ°€ μ’…λ£Œλ˜μ–΄λ„ 
       // postDelayedλŠ” λ°”λ‘œ μ •μ§€λ˜μ§€ μ•Šκ³  λ‹€μŒ 번 run λ©”μ†Œλ“œλΌ ν˜ΈμΆœ.
        mRunning = false;
        super.onDestroy();
    }




   // μ„œλΉ„μŠ€ 처리
    public void run() {
        if (!mRunning) {
            // μ„œλΉ„μŠ€ μ’…λ£Œ μš”μ²­μ΄ λ“€μ–΄μ˜¨ 경우 κ·Έλƒ₯ μ’…λ£Œ
            Log.e("MyService", "run after destory");
            return;
        } else if (--mCounter <= 0) {
            // μ§€μ •ν•œ 횟수 μ‹€ν–‰ν•˜λ©΄ 슀슀둜 μ’…λ£Œ
            Log.e("MyService", "stop Service id = "+mStartId);
            stopSelf(mStartId);
        } else {        	
            // λ‹€μŒ μž‘μ—…μ„ λ‹€μ‹œ μš”κ΅¬
            Log.e("MyService", "mCounter : " + mCounter);
            mHandler.postDelayed(this, TIMER_PERIOD);
        }
    }

   // 원격 λ©”μ†Œλ“œ ν˜ΈμΆœμ„ μœ„ν•΄ μ‚¬μš©
    // λ©”μ„œλ“œ ν˜ΈμΆœμ„ μ œκ³΅ν•˜μ§€ μ•ŠμœΌλ©΄ null을 λ°˜ν™˜
    public IBinder onBind(Intent intent) {
        return null;
    }


}

3.4. λ°°μ›Œλ³΄κΈ°μ—μ„œ ν•˜μ§€ μ•Šμ€ μ˜ˆμƒ 고렀점


  • κ·Έλ¦ΌνŒŒμΌμ„ λΆˆλŸ¬μ™”μ„κ²½μš° BitmapFactoryμ—μ„œμ˜ 이λΈμ§€ μ‚¬μ΄μ¦ˆ 변경은 이λΈμ§€λΌ 늘리고 μ„이기 λ•Œλ¬Έμ— κΈ°μ‘΄ μ•ˆλ“œλ‘œμ΄λ“œ μ–΄ν”Œ λ°°κ²½ν™”λ©΄μ—μ„œ 자λ₯΄κΈ°λ‘œ λ“€μ–΄κ°„κ²ƒκ³ΌλŠ” λ‹€λ₯΄λ‹€.
  • μ„œλΉ„μŠ€λΌ λ“±λ‘μ‹œν‚€κ³  RecieverλΌ ν†΅ν•΄ μ•ˆλ“œλ‘œμ΄λ“œ μ‹œμž‘ν›„μ— μžλ™ μž‘λ™ν•˜κ²Œ ν•΄λ†“λŠ”κ²ƒ.
  • Intent 사이간에 λ°μ΄ν„°λΌ μ£Όκ³ λ°›λŠ” 방법 μ„정해야함.
  • Picture Gallery λΆˆλŸ¬μ˜€λŠ” 방법 및 μ—¬λŸ¬κ°œ 파일 λ°›μ•„μ˜€λŠ” 방법

4. ν”„λ‘œκ·Έλž¨ μ‹œλ‚˜λ¦¬μ˜€


  • ν”„λ‘œκ·Έλž¨μ„ μΌ λ‹€.
  • 창이 λœ¬λ‹€.
    1. ν˜„μž¬ μ„μ •λ˜μ–΄μžˆλŠ” 파일 리슀트 보기
      1. 파일 리슀트 ν™”λ©΄
      2. 파일 리슀트 μΆ”κ°€/μ‚­μ œ
    2. μ‹œκ°„ μ£ΌκΈ° μ„μ •
      1. λͺ‡μ΄ˆ 주기둜 λ°”λ€ŒλŠ”μ§€. 10초 20초 30초 60초. 120초 180초.
      2. ν˜„μž¬ μ„œλΉ„μŠ€ 해지.

5. ν”„λ‘œκ·Έλž¨ μž‘μ—…ν˜„ν™© 및 둜그 κΈ°λ‘μ†Œ

5.1. μ„ ν–‰ν•™μŠ΅ν›„ μž‘μ—…ν˜„ν™© 둜그


λ‚ μ§œ 둜그
2012/4/10 Initial Import
4/10 Test버전 WallpaperChangerμž‘λ™
4/15 리슀트 μ•‘ν‹°λΉ„ν‹°λΌ κΈ°λ³ΈμœΌλ‘œ λ§Œλ“€κ³  κΈ°λ³Έ ν”„λ‘œκ·Έλž¨ κ΅¬μ‘°λΌ μž‘μŒ
4/17 LayoutμΆ”κ°€ 및 κΈ°λ³Έ Activity및 Service 파일 λ§Œλ“¬
4/18 WallPapermanagerActivityμ‹€ν–‰ 및 파일 경둜 λ°›μ•„μ˜€κΈ° μ™„μ„±
4/18 MywallpaperActivity(MainActivity)μ—μ„œ WallPapermanagerActivity둜 λ„˜κ²¨μ£ΌλŠ” λ°°κ²½ν™”λ©΄ λ¦¬μŠ€νŠΈλΌ Prototypeν˜•μœΌλ‘œ λ§Œλ“€μ–΄λ†“μŒ. WallPapermanagerActivityμ—μ„œ MywallpaperActivity(MainActivity)λ‘œλΆ€ν„° λ¦¬μŠ€νŠΈλΌ λ°›μ•„ Setν•˜κ³  λ²„νŠΌ μž…λ ₯에 따라 Setκ³Ό addλΌ ν•˜κ²Œ ν•΄λ†“μŒ. Delete의 μΆ”κ°€ κ΅¬ν˜„μ΄ ν•„μš”ν•¨.
4/19 MywallpaperActivityμ—μ„œ TimeCycleActivity둜 ν˜„μž¬ κ°’κ³Ό ν•¨κ»˜ λ„˜μ–΄κ°€λŠ” κΈ°λŠ₯ κ΅¬ν˜„. TimeCycleActivity에 enum리슀트둜 ν˜„μž¬ setting된 값을 single_choice list둜 μ„ νƒλ˜κ³  settingλ²„νŠΌ cancleλ²„νŠΌμ„ 톡해 λ‹€μ‹œ λŒμ•„μ˜€λŠ”κ²ƒ κ΅¬ν˜„.
4/22 μ»€λ‹ˆμ˜ μ•ˆλ“œλ‘œμ΄λ“œμ— μžˆλŠ” μ˜ˆμ œλŠ” Adapter + SQL을 μ¨μ„œ λ”°λ‘œ λΆ„λ¦¬λœ 예제둜 μ‹€μŠ΅ν›„ μ»€λ‹ˆμ˜ μ•ˆλ“œλ‘œμ΄λ“œ 예제 μ‹€μŠ΅
4/22 DB연동 성곡 Activityκ°„ 톡신 확인 Service μ‹€ν–‰ 성곡 κ°œμ„ μ  : 1. DBμ€‘λ³΅ν˜„μƒ 2. μ‚­μ œκ°€ μ•ˆλ¨. 3. 크기 쑰절.
4/25 PathRepositoryλΌ ArrayList둜 Parcelable객체둜 λ§Œλ“œλŠ”κ²ƒμ„ 성곡 μˆœμ„œλ„μƒμ˜ DB접근을 μ œν•œμ„ 두어야할것 κ°™μŒ. 문제점 : WallpaperManagerActivityμ—μ„œ Addμ‹œν‚€κ³  settingν•˜λŠ”λ° 객체가 날아감. 우짬.. μ•„! μš°μ„  λ§Œλ“€μ–΄λ†“κ³  settingν• λ•Œλ§Œ DB에 μ €μž₯μ‹œν‚€λŠ” λ°©μ‹μœΌλ‘œ ν•΄μ•Όκ² λ‹€.그리고 0으둜 indexκ°€ μ—†λŠ”κ²ƒκ³Ό μžˆλŠ”κ²ƒμ„ ν‘œκΈ°ν•΄μ„œ updateν˜Ήμ€ μƒˆλ‘œ λ§Œλ“€κΈ°λΌ μ‹€ν–‰ν•˜λ„λ‘ ν•˜κ³ .
4/26 전체 Activityκ°„μ˜ Parcelλ°μ΄νƒ€λΌ λ„˜κΈΈμˆ˜ 있게 μ½”λ“œλΌ λ¦¬νŽ™ν† λ§(Refactoring)함. DB의 μ—°κ²°λ¬Έμ œλΌ μ‚­μ œ μ‚½μž… λͺ©λ‘μ— flagλΌ λ‹¬μ•„ ν•΄κ²°. νŒŒμΌμ„ μ„ νƒν•΄μ„œ Path와 Name을 λ³΄μ—¬μ£ΌλŠ” Activity의 Thumnail을 λ§Œλ“€μ–΄ λ³΄μ—¬μ£Όκ²Œν•¨. Refactoringν›„ Service μž˜μž‘λ™ 확인.
4/28 WallPaperAndroidServiceμ—μ„œ Bitmap Loading방식 λ°”κΏˆ. λ¨Όμ € Loading을 ν•΄μ„œ μ€λΉ„해놓고 μˆœμ„œκ°€ 였면 화면이 λ°”λ€ŒλŠ” ν˜•μ‹μœΌλ‘œ λ°”κΏ”λ†“μŒ.μ‹œκ°„ μ„μ • μ €μž₯ DB adapter생성 및 DBμƒˆλ‘œ λ§Œλ“€μ–΄μ„œ μ €μž₯함.μ‚¬μš©μžμ˜ νŽΈμ˜λΌ μœ„ν•œ TextViewμ„λͺ… μΆ”κ°€
4/30 UI개μ„및 Splash Activity μž‘μ„±. Loading κΉŒμ§€ κΈ°λ‹€λ¦¬λŠ” κΈ°λŠ₯은 μ—†μŒ. κ°œμ„ μ‚¬ν•­ : Image Crop을 지원해야함.
5/1 Image Galleryμ—μ„œ λΆˆλŸ¬μ™€μ„œ 크기쑰절 ν•΄μ£ΌλŠ” Crop μž‘μ„±. File μž…μΆœλ ₯을 μ§€μ›ν•˜λ©΄μ„œ Side Effect둜 DB 기둝과 μ‹€μ œ File의 쑴재 μœ λ¬΄λΌ νŒλ‹¨ν•΄μ•Όν•˜λŠ” κ²½μš°κ°€ 생김

5.2. Reference


6. μž‘μ§€μ‹


  • enum의 iteration κ°€λŠ₯


public class fdfdf {

	public static void main(String[] args){
		STATE s[] = STATE.values();
		
		for(STATE s2 : s){
			System.out.println(s2.getState());
		}
		
	}
	
	private enum STATE{
		
		IMAGE_PICK_OK(0),
		FAIL(-1);
	
		private int state;
		
		private STATE(int arg){
			this.state = arg;
		}
		
		int getState(){
			return state;
		}
	}
}


  • μ΄μŠΉν•œλ‹˜μ˜ Javaμƒμ˜ enum은 λ¬Έμžμ—΄ λΉ„κ΅λ‘œ 인해 μž„λ² μ΄λ””λ“œμ™€ λ°˜λ³΅μ½”λ“œμ—μ„œλŠ” μ„±λŠ₯을 μ €ν•΄μ‹œν‚€λŠ” μš”μΈμ΄ 될수 μžˆλ‹€.
    • 사싀 확인


μ„±λŠ₯을 μœ„ν•œ μ„계
μ•ˆλ“œλ‘œμ΄λ“œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ†λ„λŠ” λΉ¨λΌμ•Όλ§Œ ν•©λ‹ˆλ‹€. 음, νš¨μœ¨μ μ΄μ–΄μ•Ό ν•œλ‹€κ³  λ§ν•˜λŠ” μͺ½μ΄ 더 μ •ν™•ν•  λ“μ‹Άλ„μš”. λ‹€μ‹œ 말해, μ œν•œλœ μ»΄ν“¨νŒ… νŒŒμ›Œμ™€ 데이터 μ €μž₯μ†Œ, μž‘μ€ ν™”λ©΄, κ°‘κ°‘ν•œ 배터리 수λͺ… 같은 λͺ¨λ°”일 μž₯치 ν™˜κ²½μ—μ„œ κ°€λŠ₯ν•œ ν•œ 효율적으둜 μ‹€ν–‰λ˜μ–΄μ•Ό ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•  λ•Œμ—λŠ” 이것을 λͺ…μ‹¬ν•˜μ„Έμš”. λ“€μ–Όμ½”μ–΄ 개발 μ»΄ν“¨ν„°μ—μ„œ μ‹€ν–‰ν•˜λŠ” 에λ¬λ ˆμ΄ν„°μ—μ„œλŠ” μΆ©λΆ„νžˆ 잘 μž‘λ™ν• μ§€λ„ λͺ¨λ₯΄μ§€λ§Œ, λͺ¨λ°”일 κΈ°κΈ°μ—μ„œ μ‹€ν–‰ν•  λ•Œμ—” 그리 잘 λ˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. β€” 졜고 μ„±λŠ₯의 λͺ¨λ°”일 기기라도 일반적인 λ°μŠ€ν¬νƒ‘ μ‹œμŠ€ν…œμ˜ μ„±λŠ₯을 λ”°λΌμž‘μ„ μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€. 그런 이유둜, λ‹€μ–‘ν•œ λͺ¨λ°”일 κΈ°κΈ°λ“€μ—κ²Œ μ΅œμƒμ˜ μ„±λŠ₯을 보μž₯ν•˜κΈ° μœ„ν•΄ μ—¬λŸ¬λΆ„μ€ 효율적인 μ½”λ“œλΌ μž‘μ„±ν•˜λ„λ‘ μ—΄μ‹¬νžˆ λ…Έλ ₯ν•˜μ…”μ•Ό ν•©λ‹ˆλ‹€.

일반적으둜, λΉ λ₯΄κ±°λ‚˜ 효율적인 μ½”λ“œλΌλŠ” 것은 λ©”λͺ¨λ¦¬ 할당을 μ΅œμ†Œν™” ν•˜κ³ , 꽉 짜인 μ½”λ“œλΌ μž‘μ„±ν•˜κ³ , νŠΉμ • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ‚˜ 잠재적으둜 μ„±λŠ₯상 λ¬Έμ œκ°€ λ λ§Œν•œ ν”„λ‘œκ·Έλž˜λ° 어법듀을 ν”Όν•˜λŠ” 것을 λ§ν•©λ‹ˆλ‹€. 객체지ν–₯ μš©μ–΄λ‘œ λ§ν•˜μžλ©΄, μ΄λŸ¬ν•œ 일이 κ°€μž₯ 빈번히 μΌμ–΄λ‚˜λŠ” 곳은 λ©”μ†Œλ“œ 레벨이며, 이와 λΉ„μŠ·ν•˜κ²Œ μ‹€μ œ μ½”λ“œ 라인듀과 반볡문 λ“±μ—μ„œ λ°œμƒν•©λ‹ˆλ‹€ .

이 λ¬Έμ„œλŠ” λ‹€μŒ μ£Όμ œλ“€μ„ λ‹€λ£Ήλ‹ˆλ‹€:

μ†Œκ°œ
객체 생성을 ν”Όν•˜λΌ
λ„μ΄ν‹°λΈŒ λ©”μ†Œλ“œλΌ μ‚¬μš©ν•˜λΌ
μΈν„°νŽ˜μ΄μŠ€λ³΄λ‹€ 가상 연결을 μ„ ν˜Έν•˜λΌ
가상 연결보닀 정적 연결을 μ„ ν˜Έν•˜λΌ
λ‚΄λΆ€μ—μ„œ Getter/Setter μ‚¬μš©μ„ ν”Όν•˜λΌ
ν•„λ“œ 참쑰듀을 μΊμ‹œν•˜λΌ
μƒμˆ˜λΌ Final둜 μ„ μ–Έν•˜λΌ
주의 깊게 ν–₯μƒλœ 반볡문(Enhanced For Loop)을 μ‚¬μš©ν•˜λΌ
μ—΄κ±°ν˜•(Enum)을 ν”Όν•˜λΌ
λ‚΄λΆ€ ν΄λž˜μŠ€μ™€ ν•¨κ»˜ νŒ¨ν‚€μ§€ λ²”μœ„λΌ μ‚¬μš©ν•˜λΌ
FloatλΌ ν”Όν•˜λΌ
μ„±λŠ₯ μ˜ˆμ‹œ 숫자 λͺ‡ 개
λ§ΊλŠ” 말
μ†Œκ°œ

μžμ› μ œν•œμ  μ‹œμŠ€ν…œμ—λŠ” 두 가지 κΈ°λ³Έ κ·œμΉ™μ΄ μžˆμŠ΅λ‹ˆλ‹€:

ν•„μš” μ—†λŠ” 일은 ν•˜μ§€ 말 것
λ©”λͺ¨λ¦¬ 할당을 ν”Όν•  수 μžˆλ‹€λ©΄ κ·Έλ ‡κ²Œ ν•  것
μ•„λž˜μ˜ λͺ¨λ“  νŒλ“€μ€ 이 두 가지 κΈ°λ³Έ μ£Όμ˜λΌ λ”°λ₯΄κ³  μžˆμŠ΅λ‹ˆλ‹€.

λˆ„κ΅°κ°€λŠ” 이 νŽ˜μ΄μ§€μƒμ˜ λ§Žμ€ 쑰언이 "μ„£λΆ€λ₯Έ μ΅œμ ν™”"λ‚˜ λ§ˆμ°¬κ°€μ§€λΌκ³  λΉ„νŒν• μ§€λ„ λͺ¨λ¦…λ‹ˆλ‹€. λΈμ‹œ μ΅œμ ν™”λŠ” λ•Œλ‘œλŠ” 효율적인 데이터 ꡬ쑰와 μ•Œκ³ λ¦¬μ¦˜μ„ κ°œλ°œν•˜λŠ” 것을 더 μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€λŠ” 것은 μ‚¬μ‹€μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ, ν•Έλ“œμ…‹κ³Ό 같은 μž„λ² λ””λ“œ κΈ°κΈ°μ—μ„œλŠ” λ•Œλ‘œλŠ” 별닀λ₯Έ 선택지가 μ—†μŠ΅λ‹ˆλ‹€. μ˜ˆλΌ λ“€μ–΄, μ—¬λŸ¬λΆ„μ΄ λ°μŠ€ν¬νƒ‘μ—μ„œ κ°œλ°œν•  λ•Œ μƒκ°ν•˜λŠ” VM의 μ„±λŠ₯에 λŒ€ν•œ 가정을 μ•ˆλ“œλ‘œμ΄λ“œμ—λ„ μ μš©ν•œλ‹€λ©΄, μ—¬λŸ¬λΆ„μ€ μ‹œμŠ€ν…œ λ©”λͺ¨λ¦¬λΌ μ†Œμ§„ν•΄λ²„λ¦¬λŠ” μ½”λ“œλΌ κ½€λ‚˜ μž‘μ„±ν•΄ 버리고 말 κ²ƒμž…λ‹ˆλ‹€. 이것은 μ—¬λŸ¬λΆ„μ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λ°”λ‹₯을 기도둝 ν•  수 μžˆμŠ΅λ‹ˆλ‹€ β€” μ‹œμŠ€ν…œμ—μ„œ λ™μž‘ν•˜λŠ” λ‹€λ₯Έ ν”„λ‘œκ·Έλž¨λ“€μ—κ²Œ 무엇을 ν•˜λŠ”μ§€ μ§€μΌœλ³΄μ„Έμš”!

이것이 λ°”λ‘œ 이 κ°€μ΄λ“œλΌμΈμ΄ μ€‘μš”ν•œ μ΄μœ μž…λ‹ˆλ‹€. μ•ˆλ“œλ‘œμ΄λ“œμ˜ 성곡은 μ—¬λŸ¬λΆ„μ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ œκ³΅ν•˜λŠ” μ‚¬μš©μž κ²½ν—˜(UX)에 달렸고, μ‚¬μš©μž κ²½ν—˜μ΄λž€ 것은 μ—¬λŸ¬λΆ„μ˜ μ½”λ“œκ°€ λΉ λ₯΄κ³  νŒ”νŒ”ν•˜κ²Œ λ°˜μ‘ν•˜λŠ”μ§€, μ•„λ‹ˆλ©΄ 느리고 λ¬΄κ±°μš΄μ§€μ— λ‹¬λ ΈμŠ΅λ‹ˆλ‹€. λͺ¨λ“  우리의 μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€μ€ 같은 μž₯μΉ˜μ—μ„œ λ™μž‘ν•  것이기 λ•Œλ¬Έμ—, μ–΄λ–€ 의λΈλ‘œ, 우리 λͺ¨λ‘ ν•¨κ»˜ 이 것듀을 지킀도둝 μ΅œμ„ μ„ λ‹€ν•΄μ•Ό ν•©λ‹ˆλ‹€. 이 λ¬Έμ„œλΌ μš΄μ „λ©΄ν—ˆλΌ λ”Έ λ•Œ λ°°μ›Œμ•Όλ§Œ ν•˜λŠ” λ„λ‘œκ΅ν†΅λ²•μ΄λΌκ³  μƒκ°ν•˜μ„Έμš”: λͺ¨λ“  이가 λ”°λ₯΄λ©΄ λ¬Έμ œμ—†μ΄ μ›ν™œν•˜κ² μ§€λ§Œ, λ”°λ₯΄μ§€ μ•ŠλŠ”λ‹€λ©΄ 사고가 λ‚  κ²ƒμ²˜λŸΌ λ§μž…λ‹ˆλ‹€.

μžμ„Έν•œ λ‚΄μš©μ„ 닀루기 전에, κ°„λ‹¨ν•œ μ£Όμ˜μ‚¬ν•­μž…λ‹ˆλ‹€: μ•„λž˜ μ„λͺ…λœ λŒ€λΆ€λΆ„μ˜ μ΄μŠˆλ“€μ€ VM이 JIT μ»΄νŒŒμΌλŸ¬μ΄λ“  μ•„λ‹ˆλ“  νš¨κ³Όμ μž…λ‹ˆλ‹€. 같은 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 두 λ©”μ†Œλ“œκ°€ 있고 interpret λ°©μ‹μ—μ„œ foo()의 싀행속도가 bar()보닀 λΉ λ₯΄λ‹€λ©΄, 컴파일 된 λ²„μ „μ—μ„œλ„ μ•„λ§ˆ foo()κ°€ bar()κ³Ό λΉ„μŠ·ν•˜κ±°λ‚˜ 더 λΉ λ₯Έ μ†λ„λΌ λ³΄μ—¬μ„ κ²ƒμž…λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬κ°€ μ—¬λŸ¬λΆ„μ„ "ꡬ해μ„"κ²ƒμ΄λΌλ˜κ°€ μΆ©λΆ„νžˆ λΉ λ₯΄κ²Œ λ§Œλ“€μ–΄μ„ κ²ƒμ΄λΌκ³  μ˜μ‘΄ν•˜λŠ” 건 ν˜„λͺ…ν•˜μ§€ λͺ»ν•˜λ‹€λŠ” 것이죠.

객체 생성을 ν”Όν•˜λΌ

객체의 생성은 κ²°μ½” κ³΅μ§œκ°€ μ•„λ‹™λ‹ˆλ‹€. μž„μ‹œ 객체듀을 μœ„ν•΄ μ“°λ ˆλ“œ-λ‹Ή(per-thread) ν• λ‹Ή 풀을 μ‚¬μš©ν•˜λŠ” μ„ΈλŒ€ν˜•(generational) GCλŠ” 더 λ‚은 λΉ„μš©μœΌλ‘œ ν• λ‹Ή ν•  수 μžˆμ§€λ§Œ, λ©”λͺ¨λ¦¬λΌ ν• λ‹Ήν•œλ‹€λŠ” 것은 λ©”λͺ¨λ¦¬λΌ ν• λ‹Ήν•˜μ§€ μ•ŠλŠ” 것 보닀 μ–Έμ œλ‚˜ 더 높은 λΉ„μš©μ΄ λ“­λ‹ˆλ‹€.

λ§Œμ•½ μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€ λ£¨ν”„μ—μ„œ κ°μ²΄λΌ ν• λ‹Ήν•œλ‹€λ©΄, 주기적으둜 가비지 μ»¬λ ‰μ…˜μ„ κ°•μš”ν•˜κ²Œ 될 것이고 μ‚¬μš©μž κ²½ν—˜μ— μžˆμ–΄μ„œ μ‘°κ·Έλ§ˆν•œ "λ”ΈκΎΉμ§ˆ(거뢁함)"을 λ§Œλ“€κ²Œ 될 κ²λ‹ˆλ‹€.

그러λ€λ‘œ, ν•„μš”λ‘œ ν•˜μ§€ μ•ŠλŠ” 객체 생성을 ν”Όν•΄μ•Ό ν•©λ‹ˆλ‹€. 도움이 될 λͺ‡ 가지 μ˜ˆμ œλ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€.

μž…λ ₯ 데이터 μ…‹μ—μ„œ λ¬Έμžμ—΄μ„ μΆ”μΆœν•  λ•Œ, 볡사 μƒμ„±λœ 것 λŒ€μ‹  원본 λ°μ΄ν„°μ˜ λΆ€λΆ„λ¬Έμžμ—΄μ„ λ°›μœΌμ‹­μ‹œμ˜€. μƒˆλ‘œμš΄ String 객체가 λ§Œλ“€μ–΄μ‘Œλ”λΌλ„ 원본 λ°μ΄ν„°μ˜ char[]을 κ³΅μœ ν•  κ²ƒμž…λ‹ˆλ‹€.
λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œκ°€ 있고 κ·Έ κ²°κ³Όκ°€ μ–Έμ œλ‚˜ StringBuffer에 λ”ν•΄μ§€κ²Œ λ˜λŠ” κ²½μš°μ— μžˆλ‹€λ©΄, 짧은 수λͺ…μ˜ μž„μ‹œ κ°μ²΄λΌ μƒμ„±ν•˜λŠ” λŒ€μ‹  μ§μ ‘μ μœΌλ‘œ λ”ν•΄μ§€λŠ” λ°©μ‹μœΌλ‘œ μ‹λ³„μžμ™€ κ΅¬ν˜„λ°©μ‹μ„ λ°”κΎΈμ„Έμš”.
μ€ λ” 급진적인 μ•„μ΄λ””μ–΄λŠ” 닀차원 배열을 λ³‘λ ¬μ˜ 단일 일 차원 λ°°μ—΄λ‘œ μž˜λΌλ‚΄λŠ” κ²ƒμž…λ‹ˆλ‹€:

int 배열은 Integer 배열보닀 더 μ’‹μŠ΅λ‹ˆλ‹€λ§Œ, μ΄κ²ƒμœΌλ‘œ λ˜ν•œ intν˜•μ˜ 두 병렬 배열이 (int,int) 객체의 배열보닀 더 많이 νš¨κ³Όμ μ΄λΌλŠ” 사싀을 μΆ”λ‘ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λ§Œμ•½ (Foo,Bar) νŠœν”Œλ‘œ μ €μž₯ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆλΌ κ΅¬ν˜„ν•  ν•„μš”κ°€ μžˆλ‹€λ©΄, 직접 λ§Œλ“  (Foo,Bar) 객체의 단일 배열보닀 두 개의 병렬 Foo[] 와 Bar[] 배열이 일반적으둜 λ”μš± 더 μ’‹λ‹€λŠ” 것을 κΈ°μ–΅ν•˜μ‹­μ‹œμ˜€. (λ¬Όλ‘ , λ‹€λ₯Έ μ½”λ“œλ“€μ΄ μ ‘κ·Όν•΄μ•Ό ν•˜λŠ” APIλΌ μ„계할 λ•Œμ—λŠ” μ˜ˆμ™Έκ°€ μžˆμŠ΅λ‹ˆλ‹€; 이 경우 μž‘μ€ 속도 ν–₯상을 λ…Έλ¦¬λŠ” 것 보닀 쒋은 APIμ„계가 항상 μ’‹μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ—¬λŸ¬λΆ„μ˜ λ‚΄λΆ€ μ½”λ“œλΌ μž‘μ„±ν•  λ•Œμ—λŠ” κ°€λŠ₯ν•œ ν•œ 효율적인 μ½”λ“œκ°€ λ˜λ„λ‘ ν•΄μ•Ό ν•˜κ² μŠ΅λ‹ˆλ‹€.)
일반적으둜, κ°€λŠ₯ν•˜λ‹€λ©΄ 짧은 수λͺ…μ˜ μž„μ‹œ 객체 생성을 ν”Όν•˜μ‹­μ‹œμ˜€. 더 적은 객체듀을 λ§Œλ“ λ‹€λŠ” 것은 μ‚¬μš©μž κ²½ν—˜μ— 직접적인 영ν–₯을 μ£ΌλŠ” 가비지 μ»¬λ ‰μ…˜ μ„μ—¬μ€Œμ„ λœ»ν•©λ‹ˆλ‹€.

λ„μ΄ν‹°λΈŒ λ©”μ†Œλ“œλΌ μ‚¬μš©ν•˜λΌ

λ¬Έμžμ—΄μ„ μ²˜λ¦¬ν•  λ•Œ, String.indexOf(), String.lastIndexOf() 와 κ·Έ λ°–μ˜ νŠΉλ³„ν•œ λ©”μ†Œλ“œλΌ μ‚¬μš©ν•˜λŠ” 것을 μ£Όμ €ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. 이 λ©”μ†Œλ“œλ“€μ€ λŒ€μ²΄μ μœΌλ‘œ, μžλ°” λ£¨ν”„λ‘œ 된 것 보닀 λŒ€λž΅ 10-100λ°° λΉ λ₯Έ C/C++ μ½”λ“œλ‘œ κ΅¬ν˜„μ΄ λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

이 μ‘°μ–Έμ˜ λ°˜λŒ€μ  츑면은 λ„μ΄ν‹°λΈŒ λ©”μ†Œλ“œλΌ ν˜ΈμΆœν•˜λŠ” 것이 interpretλ°©μ‹μ˜ λ©”μ†Œλ“œ ν˜ΈμΆœλ³΄λ‹€ 더 λΉ„μš©μ΄ λ†’λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. ν”Όν•  수 μžˆλ‹€λ©΄, μ‚¬μ†Œν•œ κ³„μ‚°μ—λŠ” λ„μ΄ν‹°λΈŒ λ©”μ†Œλ“œλΌ μ‚¬μš©ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€.

μΈν„°νŽ˜μ΄μŠ€λ³΄λ‹€ 가상 연결을 μ„ ν˜Έν•˜λΌ

μ—¬λŸ¬λΆ„μ΄ HashMap κ°μ²΄λΌ ν•˜λ‚˜ 가지고 μžˆλ‹€κ³  ν•©μ‹œλ‹€. μ—¬λŸ¬λΆ„μ€ HashMapμ΄λ‚˜ 제λ„λ¦­ Map 으둜 선언을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Map myMap1 = new HashMap();
HashMap myMap2 = new HashMap();
어떀것이 더 μ’‹μ€κ°€μš”?

전톡적인 μ§€ν˜œμ—μ„œλŠ” Map을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€κ³  ν•  κ²ƒμž…λ‹ˆλ‹€. Map μΈν„°νŽ˜μ΄μŠ€λΌ κ΅¬ν˜„ν•œ μ–΄λ–€ κ²ƒμœΌλ‘œλΌλ„ κ΅¬ν˜„μ²΄λΌ λ°”κΏ€ 수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 전톡적인 μ§€ν˜œλŠ” 전톡적인 ν”„λ‘œκ·Έλž˜λ°μ—λŠ” λ§žμŠ΅λ‹ˆλ‹€λ§Œ, μž„λ² λ””λ“œ μ‹œμŠ€ν…œμ—λŠ” 그닀지 λŒ€λ‹¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μΈν„°νŽ˜μ΄μŠ€ μ°Έμ‘°λΌ ν†΅ν•΄ ν˜ΈμΆœν•˜λŠ” 것은 λͺ…ν™•ν•œ μ°Έμ‘°λΌ ν†΅ν•œ 가상 λ©”μ†Œλ“œ ν˜ΈμΆœλ³΄λ‹€ 2λ°° 더 μ†Œμš”λ  수 μžˆμŠ΅λ‹ˆλ‹€.

μ—¬λŸ¬λΆ„μ΄ ν•˜λŠ” 일에 μ ν•©ν•˜μ—¬ HashMapμ‚¬μš©μ„ μ„ νƒν–ˆλ‹€λ©΄ Map으둜 ν˜ΈμΆœν•˜λŠ” 것은 거의 κ°€μΉ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€. μ½”λ“œλΌ λ¦¬νŒ©ν„°λ§ ν•΄ μ£ΌλŠ” IDE의 κ°€λŠ₯성을 κ³ λ €ν•΄ 보더라도, Map으둜 ν˜ΈμΆœν•˜λŠ” 것은 큰 κ°€μΉ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€. μ—¬λŸ¬λΆ„μ΄ μ½”λ“œμ˜ λ°©ν–₯을 ν™•μ‹ ν•˜μ§€ λͺ»ν•œλ‹€ 해도 λ§μž…λ‹ˆλ‹€. (λ‹€μ‹œκΈˆ μ΄μ§€λ§Œ, 곡용 APIλŠ” μ˜ˆμ™Έμž…λ‹ˆλ‹€: μž‘μ€ μ„±λŠ₯ 고렀보닀 쒋은 APIκ°€ μ–Έμ œλ‚˜ μœΌλœΈμž…λ‹ˆλ‹€.)

가상 연결보닀 정적 연결을 μ„ ν˜Έν•˜λΌ

λ§Œμ•½ 객체의 ν•„λ“œμ— μ ‘κ·Όν•  ν•„μš”κ°€ μ—†λ‹€λ©΄, μ—¬λŸ¬λΆ„μ˜ λ©”μ†Œλ“œλΌ μ •μ (static)으둜 λ§Œλ“œμ„Έμš”. 가상 λ©”μ†Œλ“œ ν…Œμ΄λΈ”μ„ ν•„μš”λ‘œ ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 그게 더 λΉ λ₯΄κ²Œ λΆˆλ €μ§‘λ‹ˆλ‹€. λ˜ν•œ, λ©”μ†Œλ“œ μ‹λ³„μžλΌ λ³΄κ³  λ©”μ†Œλ“œ 호좜이 객체의 μƒνƒœλΌ λ°”κΏ€ 수 μ—†λ‹€κ³  말할 수 있으λ€λ‘œ, 쒋은 κ΄€μŠ΅μ΄ λ©λ‹ˆλ‹€.

λ‚΄λΆ€μ—μ„œ Getter/Setter μ‚¬μš©μ„ ν”Όν•˜λΌ

C++와 같은 λ„μ΄ν‹°λΈŒ μ–Έμ–΄μ—μ„œ ν•„λ“œμ— μ§μ ‘μ μœΌλ‘œ μ ‘κ·Όν•˜λŠ” 것 (예. i = mCount) 보닀 getterλΌ μ‚¬μš©ν•˜λŠ” 것 (i = getCount())은 일반적인 κ΄€μŠ΅μž…λ‹ˆλ‹€. 이 방법은 C++μ—μ„œλŠ” ν›Œλ₯­ν•œ μŠ΅κ΄€μž…λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ 항상 접근을 inlineν™” ν•  수 μžˆλŠ” μ»΄νŒŒμΌλŸ¬λΌ μ‚¬μš©ν•˜κ³  있고, ν•„λ“œμ— 접근을 μ œν•œν•˜κ±°λ‚˜ 디버그 ν•΄μ•Ό ν•œλ‹€λ©΄ μ–Έμ œλ‚˜ μ½”λ“œλΌ μΆ”κ°€ν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

μ•ˆλ“œλ‘œμ΄λ“œμ—μ„œλŠ” λ‚˜μœ μƒκ°μž…λ‹ˆλ‹€. 가상 λ©”μ†Œλ“œ ν˜ΈμΆœμ€ μΈμŠ€ν„΄μŠ€ ν•„λ“œ 참쑰보닀 더 λΉ„μš©μ΄ λ†’μŠ΅λ‹ˆλ‹€. 일반적인 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ° κ΄€μŠ΅μ— λ”°λ₯΄κ±°λ‚˜, 곡용 μΈν„°νŽ˜μ΄μŠ€μ—μ„œ getter, setter을 κ°€μ§€λŠ” 것은 μ΄μΉ˜μ— λ§žμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 클래슀 λ‚΄λΆ€μ—μ„œλŠ” μ–Έμ œλ‚˜ μ§μ ‘μ μœΌλ‘œ ν•„λ“œ 접근을 ν•΄μ•Όν•©λ‹ˆλ‹€.

ν•„λ“œ 참쑰듀을 μΊμ‹œν•˜λΌ

객체의 ν•„λ“œμ— μ ‘κ·Όν•˜λŠ” 것은 지역 λ³€μˆ˜μ— μ ‘κ·Όν•˜λŠ” 것 보닀 더 λŠλ¦½λ‹ˆλ‹€. μ΄λ ‡κ²Œ μž‘μ„±ν•˜λŠ” 것 λŒ€μ‹ :

for (int i = 0; i < this.mCount; i++)
      dumpItem(this.mItems[i]);
μ΄λ ‡κ²Œ ν•˜μ‹­μ‹œμ˜€:

  int count = this.mCount;
  Item[] items = this.mItems;
 
  for (int i = 0; i < count; i++)
      dumpItems(items[i]);
(멀버 λ³€μˆ˜λΌλŠ” 것을 λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•΄ λͺ…μ‹œμ μΈ "this"λΌ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.)

μœ μ‚¬ν•œ κ°€μ΄λ“œλΌμΈμ€, κ²°μ½” "for"문의 두 번째 μ‘°κ±΄μ—μ„œ λ©”μ†Œλ“œλΌ ν˜ΈμΆœν•˜μ§€ λ§λΌλŠ” κ²ƒμž…λ‹ˆλ‹€. μ˜ˆλΌ λ“€μ–΄, λ‹€μŒ μ½”λ“œλŠ” κ°„λ‹¨ν•˜κ²Œ int κ°’μœΌλ‘œ 캐쉬 ν•  수 μžˆλŠ” κ²½μš°μž„μ—λ„ 큰 λ‚­λΉ„κ°€ λ˜λŠ” getCount()λ©”μ†Œλ“œλΌ λ§€λ²ˆ 반볡 λ§ˆλ‹€ μ‹€ν–‰ν•˜κ²Œ λ©λ‹ˆλ‹€:

for (int i = 0; i < this.getCount(); i++)
    dumpItems(this.getItem(i));
μΈμŠ€ν„΄μŠ€ ν•„λ“œλΌ ν•œλ²ˆ 이상 μ ‘κ·Όν•΄μ•Ό ν•œλ‹€λ©΄, 지역 λ³€μˆ˜λΌ λ§Œλ“œλŠ” 것 λ˜ν•œ 쒋은 μƒκ°μž…λ‹ˆλ‹€. μ˜ˆλΌ λ“€μ–΄:

    protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) {
        if (isHorizontalScrollBarEnabled()) {
            int size = mScrollBar.getSize(false);
            if (size <= 0) {
                size = mScrollBarSize;
            }
            mScrollBar.setBounds(0, height - size, width, height);
            mScrollBar.setParams(
                    computeHorizontalScrollRange(),
                    computeHorizontalScrollOffset(),
                    computeHorizontalScrollExtent(), false);
            mScrollBar.draw(canvas);
        }
    }
mScrollBar 멀버 ν•„λ“œμ— λ„κ°œμ˜ λΆ„λ¦¬λœ μ°Έμ‘°κ°€ μžˆμŠ΅λ‹ˆλ‹€. 지역 μŠ€νƒ λ³€μˆ˜λ‘œ mScrollBarλΌ μΊμ‹± ν•¨μœΌλ‘œμ¨, λ„κ°œμ˜ 멀버 ν•„λ“œ μ°Έμ‘°κ°€ λ”μš± 효율적인 λ„κ°œμ˜ μŠ€νƒ λ³€μˆ˜ 참쑰둜 λ°”λ€Œμ—ˆμŠ΅λ‹ˆλ‹€.

덧뢙여 λ§ν•˜μžλ©΄, λ©”μ†Œλ“œ μΈμžλ“€μ€ 지역 λ³€μˆ˜μ™€ 같은 μ„±λŠ₯ νŠΉμ„±μ„ κ°€μ§‘λ‹ˆλ‹€.

μƒμˆ˜λΌ Final둜 μ„ μ–Έν•˜λΌ

클래슀의 상단에 μžˆλŠ” λ‹€μŒ 선언을 κ³ λ €ν•΄ λ΄…μ‹œλ‹€:

static int intVal = 42;
static String strVal = "Hello, world!";
μ»΄νŒŒμΌλŸ¬λŠ” ν΄λž˜μŠ€κ°€ 처음 μ‚¬μš©λ  λ•Œ μ‹€ν–‰ν•˜κ²Œ λ˜λŠ” <clinit>라 λΆˆλ¦¬λŠ” '클래슀 μ΄ˆκΈ°ν™” λ©”μ†Œλ“œ'λΌ μƒμ„±ν•©λ‹ˆλ‹€. 이 λ©”μ†Œλ“œκ°€ intVal에 42 값을 μ €μž₯ν•˜κ³ , strValμ—λŠ” 클래슀파일 문자 μƒμˆ˜ ν…Œμ΄λΈ”λ‘œλΆ€ν„° μ°Έμ‘°λΌ μΆ”μΆœν•˜μ—¬ μ €μž₯ν•©λ‹ˆλ‹€. λ‚˜μ€‘μ— 참쑰될 λ•Œ 이 값듀은 ν•„λ“œ 참쑰둜 μ ‘κ·Όλ©λ‹ˆλ‹€.

μ΄λΌ "final" ν‚€μ›Œλ“œλ‘œ ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€:

static final int intVal = 42;
static final String strVal = "Hello, world!";
ν΄λž˜μŠ€λŠ” 더이상 <clinit> λ©”μ†Œλ“œλΌ ν•„μš”λ‘œ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ μƒμˆ˜λ“€μ€ VM에 μ˜ν•΄ μ§μ ‘μ μœΌλ‘œ 닀루어 μ§€λŠ” '클래슀파일 정적 ν•„λ“œ 초기자'에 λ“€μ–΄κ°€κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.intVal의 μ½”λ“œ 접근은 μ§μ ‘μ μœΌλ‘œ μ •μˆ˜ κ°’ 42λΌ μ‚¬μš©ν•  것이고, strVal둜의 접근은 ν•„λ“œ 참쑰보닀 μƒλŒ€μ μœΌλ‘œ μ €λ ΄ν•œ "λ¬Έμžμ—΄ μƒμˆ˜" λͺ…령을 μ‚¬μš©ν•˜κ²Œ 될 κ²ƒμž…λ‹ˆλ‹€.

"final"으둜 λ©”μ†Œλ“œλ‚˜ 클래슀의 선언을 ν•˜λŠ” 것은 즉각적인 μ„±λŠ₯ 이득을 μ£Όμ§€λŠ” λͺ»ν•˜μ§€λ§Œ, νŠΉμ •ν•œ μ΅œμ ν™”λΌ κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€. μ˜ˆλΌ λ“€μ–΄, μ»΄νŒŒμΌλŸ¬κ°€ μ„œλΈŒν΄λž˜μŠ€μ— μ˜ν•΄ μ˜€λ²„λΌμ΄λ“œλ  수 μ—†λŠ” "getter"λ©”μ†Œλ“œλΌ μ•Œκ³  μžˆλ‹€λ©΄, λ©”μ†Œλ“œ ν˜ΈμΆœμ„ inlineν™” ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ—¬λŸ¬λΆ„μ€ λ˜ν•œ 지역 λ³€μˆ˜λΌ final둜 μ„ μ–Έν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이것은 결정적인 μ„±λŠ₯ 이득은 μ—†μŠ΅λ‹ˆλ‹€. 지역 λ³€μˆ˜μ—λŠ” 였직 μ½”λ“œλΌ λͺ…ν™•νžˆ ν•˜κΈ° μœ„ν•΄μ„œ "final"을 μ‚¬μš©ν•©λ‹ˆλ‹€ (λ˜λŠ” μ˜ˆλΌ λ“€μ–΄ 읡λͺ… λ‚΄λΆ€ ν΄λž˜μŠ€λΌ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λ©΄ κ°€λŠ₯).

주의 깊게 ν–₯μƒλœ 반볡문(Enhanced For Loop)을 μ‚¬μš©ν•˜λΌ

ν–₯μƒλœ 반볡문(λ•Œλ‘œ "for-each"둜 μ•Œλ €μ§„ 반볡문)은 Iterable μΈν„°νŽ˜μ΄μŠ€λΌ κ΅¬ν˜„ν•œ μ»¬λ ‰μ…˜λ“€μ„ μœ„ν•΄ μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ κ°μ²΄λ“€λ‘œ, λ°˜λ³΅μžλŠ” hasNext() 와 next()을 ν˜ΈμΆœν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€λΌ λ§Œλ“€κΈ° μœ„ν•΄ ν• λ‹Ήλ©λ‹ˆλ‹€. ArrayList의 경우 μ—¬λŸ¬λΆ„μ΄ 직접 νƒμƒ‰ν•˜λŠ” 것이 쒋을 수 μžˆμŠ΅λ‹ˆλ‹€λ§Œ, λ‹€λ₯Έ μ»¬λ ‰μ…˜λ“€μ—μ„œλŠ” ν–₯μƒλœ 반볡문 ꡬ문이 λͺ…μ‹œμ μΈ 반볡자의 μ‚¬μš©κ³Ό λ™λ“±ν•œ μ„±λŠ₯을 λ³΄μ—¬μ€λ‹ˆλ‹€.

κ·ΈλŸΌμ—λ„, λ‹€μŒ μ½”λ“œλ‘œ ν–₯μƒλœ 반볡문의 만μ±μŠ€λŸ¬μš΄ μ‚¬μš©λ²•μ„ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€:

public class Foo {
    int mSplat;
    static Foo mArray[] = new Foo[27];

    public static void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; i++) {
            sum += mArray[i].mSplat;
        }
    }

    public static void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;

        for (int i = 0; i < len; i++) {
            sum += localArray[i].mSplat;
        }
    }

    public static void two() {
        int sum = 0;
        for (Foo a: mArray) {
            sum += a.mSplat;
        }
    }
}
zero() λŠ” λ°˜λ³΅λ˜λŠ” 맀 μ£ΌκΈ°λ§ˆλ‹€ 정적 ν•„λ“œλΌ λ‘ 번 λΆ€λ₯΄κ³  λ°°μ—΄μ˜ κΈΈμ΄λΌ ν•œλ²ˆ μ–»μŠ΅λ‹ˆλ‹€.

one() 은 μ°Έμ‘°λΌ ν”Όν•˜κΈ° μœ„ν•΄ 지역 λ³€μˆ˜λ‘œ λͺ¨λ“  것을 λŒμ–΄λƒˆμŠ΅λ‹ˆλ‹€.

two() λŠ” μžλ°” μ–Έμ–΄μ˜ 1.5λ²„μ „μ—μ„œ μ†Œκ°œλœ ν–₯μƒλœ 반볡문 ꡬ문을 μ‚¬μš©ν•©λ‹ˆλ‹€. μ»΄νŒŒμΌλŸ¬μ— μ˜ν•΄ μƒμ„±λœ μ½”λ“œλŠ” λ°°μ—΄ 참쑰와 λ°°μ—΄μ˜ κΈΈμ΄λΌ μ§€μ—­ λ³€μˆ˜λ‘œ 볡사해주어, λ°°μ—΄μ˜ λͺ¨λ“  μ›μ†ŒλΌ νƒμƒ‰ν•˜λŠ”λ° 쒋은 선택이 될 수 μžˆμŠ΅λ‹ˆλ‹€. μ£Ό 루프 내에 좔가적인 지역 읽기/μ €μž₯이 λ§Œλ“€μ–΄μ§€κ³ (λͺ…λ°±ν•˜κ²Œ "a"에 μ €μž₯), one()보닀 μͺΌκΈˆ 느리고 4 λ°”μ΄νŠΈ κΈΈμ–΄μ§€κ²Œ ν•˜κΈ΄ ν•©λ‹ˆλ‹€.

μ€ λ” λͺ…ν™•ν•˜κ²Œ λͺ¨λ“  것을 μ’…ν•©ν•˜μžλ©΄: ν–₯μƒλœ 반볡문 ꡬ문은 λ°°μ—΄κ³Ό 잘 λ™μž‘ν•˜μ§€λ§Œ, 좔가적인 객체 생성이 있게 λ˜λŠ” Iterable 객체와 ν•¨κ»˜ μ‚¬μš©ν•  λ•Œμ—” 쑰심해야 ν•©λ‹ˆλ‹€.

μ—΄κ±°ν˜•(Enum)을 ν”Όν•˜λΌ

μ—΄κ±°ν˜•μ€ 맀우 νŽΈλ¦¬ν•©λ‹ˆλ‹€, κ·ΈλŸ¬λ‚˜ λΆˆμš΄ν•˜κ²Œλ„ 크기와 속도 μΈ‘λ©΄μ—μ„œ κ³ ν†΅μŠ€λŸ¬μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€. 예λΌλ“€μ–΄, λ‹€μŒμ˜ μ½”λ“œλŠ”:

public class Foo {
   public enum Shrubbery { GROUND, CRAWLING, HANGING }
}
900 λ°”μ΄νŠΈμ˜ 클래슀 파일 (Foo$Shrubbery.class) 둜 λ³€ν™˜λ©λ‹ˆλ‹€. 처음 μ‚¬μš©ν•  λ•Œ, 클래슀 μ΄ˆκΈ°μžλŠ” 각각의 μ—΄κ±°ν™”λœ 값듀을 ν‘œκΈ°ν™” ν•˜λŠ” κ°μ²΄μƒμ˜ <init>λ©”μ†Œλ“œλΌ ν˜ΈμΆœν•©λ‹ˆλ‹€. 각 κ°μ²΄λŠ” 정적 ν•„λ“œλΌ κ°€μ§€κ²Œ 되고 총 셋은 λ°°μ—΄("$VALUES"라 λΆˆλ¦¬λŠ” 정적 ν•„λ“œ)에 μ €μž₯λ©λ‹ˆλ‹€. 단지 μ„Έ 개의 μ •μˆ˜λΌ μœ„ν•΄ λ§Žμ€ μ½”λ“œμ™€ λ°μ΄ν„°λΌ ν•„μš”λ‘œ ν•˜κ²Œ λ©λ‹ˆλ‹€.

λ‹€μŒ μ½”λ“œ:

Shrubbery shrub = Shrubbery.GROUND;
λŠ” 정적 ν•„λ“œ μ°Έμ‘°λΌ μ•ΌκΈ°ν•©λ‹ˆλ‹€. "GROUND"κ°€ 정적 final int μ˜€λ”λΌλ©΄, μ»΄νŒŒμΌλŸ¬λŠ” μ•Œλ €μ§„ μƒμˆ˜λ‘œμ„œ 닀루고, inlineν™” ν–ˆμ„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

λ¬Όλ‘ , λ°˜λŒ€μ  μΈ‘λ©΄μ—μ„œ μ—΄κ±°ν˜•μœΌλ‘œ 더 쒋은 APIλΌ λ§Œλ“€ 수 있고 μ–΄λ–€ κ²½μš°μ—” 컴파일-νƒ€μž„ κ°’ κ²€μ‚¬λΌ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ ν†΅μƒμ˜ κ΅ν™˜μ‘°κ±΄(trade-off)이 μ μš©λ©λ‹ˆλ‹€: λ°˜λ“œμ‹œ 곡용 APIμ—λ§Œ μ—΄κ±°ν˜•μ„ μ‚¬μš©ν•˜κ³ , μ„±λŠ₯λ¬Έμ œκ°€ μ€‘μš”ν•  λ•Œμ—λŠ” μ‚¬μš©μ„ ν”Όν•˜μ‹­μ‹œμ˜€.

μ–΄λ–€ ν™˜κ²½μ—μ„œλŠ” ordinal() λ©”μ†Œλ“œλΌ ν†΅ν•΄ μ •μˆ˜ κ°’ μ—΄κ±°λΌ κ°–λŠ” 것이 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€. μ˜ˆλΌ λ“€μ–΄, λ‹€μŒ μ½”λ“œλΌ:

for (int n = 0; n < list.size(); n++) {
    if (list.items[n].e == MyEnum.VAL_X)
       // do stuff 1
    else if (list.items[n].e == MyEnum.VAL_Y)
       // do stuff 2
}
λ‹€μŒ μ½”λ“œλ‘œ λŒ€μ‹ ν•©λ‹ˆλ‹€:

   int valX = MyEnum.VAL_X.ordinal();
   int valY = MyEnum.VAL_Y.ordinal();
   int count = list.size();
   MyItem items = list.items();

   for (int  n = 0; n < count; n++)
   {
        int  valItem = items[n].e.ordinal();

        if (valItem == valX)
          // do stuff 1
        else if (valItem == valY)
          // do stuff 2
   }
λ•Œλ‘œλŠ”, 보μž₯ν•  수 μ—†μŠ΅λ‹ˆλ‹€λ§Œ, 이것이 더 λΉ λΌ μˆ˜ μžˆμŠ΅λ‹ˆλ‹€.

λ‚΄λΆ€ ν΄λž˜μŠ€μ™€ ν•¨κ»˜ νŒ¨ν‚€μ§€ λ²”μœ„λΌ μ‚¬μš©ν•˜λΌ

λ‹€μŒ 클래슀 μ •μ˜λΌ κ³ λ €ν•΄ λ΄…μ‹œλ‹€:

public class Foo {
    private int mValue;

    public void run() {
        Inner in = new Inner();
        mValue = 27;
        in.stuff();
    }

    private void doStuff(int value) {
        System.out.println("Value is " + value);
    }

    private class Inner {
        void stuff() {
            Foo.this.doStuff(Foo.this.mValue);
        }
    }
}
μ—¬κΈ°μ„œ μ£Όλͺ©ν•΄μ•Ό ν•  μ€‘μš”ν•œ 것은, μ™ΈλΆ€ 클래슀의 private λ©”μ†Œλ“œμ™€ private μΈμŠ€ν„΄μŠ€ ν•„λ“œμ— 직접 μ ‘κ·Όν•˜κ³  μžˆλŠ” λ‚΄λΆ€ 클래슀(Foo$Inner)λΌ μ •μ˜ν–ˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이것은 μ λ²•ν•˜κ³ , μ½”λ“œλŠ” κΈ°λŒ€ν–ˆλ˜ λŒ€λ‘œ "Value is 27"을 좜λ ₯ν•©λ‹ˆλ‹€.

λ¬Έμ œλŠ” Foo$InnerλŠ” κΈ°μˆ μ μœΌλ‘œλŠ” (λΉ„λ°€λ‘œμ¨) μ™„μ „νžˆ λΆ„λ¦¬λœ, Foo의 private λ©€λ²„λ‘œ 직접적인 접근을 ν•˜λŠ” 것은 μ λ²•ν•˜μ§€ λͺ»ν•œ ν΄λž˜μŠ€λΌλŠ” 것 μž…λ‹ˆλ‹€. 이 μ°¨μ΄λΌ μ—°κ²°μ§“κΈ° μœ„ν•΄, μ»΄νŒŒμΌλŸ¬λŠ” 두 개의 ν•©μ„± λ©”μ†Œλ“œλΌ λ§Œλ“­λ‹ˆλ‹€:

/*package*/ static int Foo.access$100(Foo foo) {
    return foo.mValue;
}
/*package*/ static void Foo.access$200(Foo foo, int value) {
    foo.doStuff(value);
}
λ‚΄λΆ€ 클래슀 μ½”λ“œλŠ” μ™ΈλΆ€ ν΄λž˜μŠ€μ— μžˆλŠ” "mValue" ν•„λ“œμ— μ ‘κ·Όν•˜κ±°λ‚˜ "doStuff" λ©”μ†Œλ“œλΌ λΆ€λ₯΄κΈ° μœ„ν•΄ 이 정적 λ©”μ†Œλ“œλΌ λΆ€λ¦…λ‹ˆλ‹€. 이것은 이 μ½”λ“œκ°€ 결ꡭ은 직접적인 방법 λŒ€μ‹  μ ‘κ·Όμž λ©”μ†Œλ“œλΌ ν†΅ν•΄ 멀버 ν•„λ“œμ— μ ‘κ·Όν•˜κ³  μžˆλ‹€λŠ” 것을 λœ»ν•©λ‹ˆλ‹€. 이전에 μš°λ¦¬λŠ” μ–΄μ§Έμ„œ μ ‘κ·Όμžκ°€ 직접적인 ν•„λ“œ 접근보닀 λŠλ¦°μ§€μ— λŒ€ν•΄ 이야기 ν–ˆμ—ˆλŠ”λ°, 이 λ¬Έμ œλ‘œμ„œ "보이지 μ•ŠλŠ”" μ„±λŠ₯ 타격 μΈ‘λ©΄μ—μ„œ νŠΉμ • μ–Έμ–΄μ˜ 어법이 μ•ΌκΈ°ν•˜κ²Œ λ˜λŠ” λ¬Έμ œμ— λŒ€ν•œ μ˜ˆμ œκ°€ 될 수 μžˆκ² μŠ΅λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” λ‚΄λΆ€ ν΄λž˜μŠ€κ°€ μ ‘κ·Όν•˜λŠ” ν•„λ“œμ™€ λ©”μ†Œλ“œ 선언에 private λ²”μœ„κ°€ μ•„λ‹Œ package λ²”μœ„λΌ κ°€μ§€λ„λ‘ ν•¨μœΌλ‘œμ¨ ν”Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이둜써 λ”μš± λΉ λ₯΄κ²Œ λ™μž‘ν•˜κ²Œ 되고 μžλ™ μƒμ„±λ˜λŠ” λ©”μ†Œλ“œμ— μ˜ν•œ μ˜€λ²„ν—€λ“œλΌ μ œκ±°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (λΆˆμš΄ν•˜κ²Œλ„ 이 λ˜ν•œ μ§μ ‘μ μœΌλ‘œ 같은 νŒ¨ν‚€μ§€ λ‚΄μ˜ λ‹€λ₯Έ ν΄λž˜μŠ€λ“€μ΄ ν•„λ“œλ“€μ— μ ‘κ·Όν•  수 μžˆλ‹€λŠ” 것을 λœ»ν•˜κ²Œ 되며, λͺ¨λ“  ν•„λ“œλ“€μ€ private둜 ν•΄μ•Ό ν•œλ‹€λŠ” ν‘œμ€μ μΈ OO κ΄€μŠ΅μ— 거슀λ₯΄κ²Œ λ©λ‹ˆλ‹€. λ‹€μ‹œ ν•œλ²ˆ 더 λ§ν•˜μžλ©΄, 곡용 APIλΌ μ„κ³„ν•˜κ²Œ λœλ‹€λ©΄ 이 μ΅œμ ν™”λΌ μ‚¬μš©ν•˜λŠ” 것을 μ‘°μ‹¬μŠ€λŸ½κ²Œ κ³ λΌν•΄μ•Όλ§Œ ν•  κ²ƒμž…λ‹ˆλ‹€.)

FloatλΌ ν”Όν•˜λΌ

νŽœν‹°μ—„ CPUκ°€ μΆœμ‹œλ˜κΈ° μ „, κ²Œμž„ μ œμž‘μžλ“€μ—κ² μ •μˆ˜ 계산에 μ΅œμ„ μ„ λ‹€ν•˜λŠ” 것이 μΌλ°˜μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€. νŽœν‹°μ—„κ³Ό ν•¨κ»˜ λΆ€λ™μ†Œμˆ˜μ  계산 보쑰 ν”„λ‘œμ„Έμ„œλŠ” μΌμ²΄ν˜•μ΄ λ˜μ—ˆκ³ , μ •μˆ˜μ™€ λΆ€λ™μ†Œμˆ˜μ  연산을 λ„£μŒμ— 따라 μˆœμˆ˜ν•˜κ²Œ μ •μˆ˜ κ³„μ‚°λ§Œμ„ μ‚¬μš©ν•˜λŠ” 것 보닀 κ²Œμž„μ€ 더 λΉ λ₯΄κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 자유둭게 λΆ€λ™μ†Œμˆ˜μ μ„ μ‚¬μš©ν•˜λŠ” 것은 λ°μŠ€ν¬νƒ‘ μ‹œμŠ€ν…œμ—μ„œλŠ” μΌλ°˜μ μž…λ‹ˆλ‹€.

λΆˆμš΄ν•˜κ²Œλ„, μž„λ² λ””λ“œ ν”„λ‘œμ„Έμ„œμ—κ²ŒλŠ” λΉˆλ²ˆν•˜κ²Œ ν•˜λ“œμ›¨μ–΄μ μœΌλ‘œ λΆ€λ™μ†Œμˆ˜μ  계산이 μ œκ³΅λ˜μ§€ μ•Šκ³  μžˆμ–΄, "float" 와 "double"의 λͺ¨λ“  계산이 μ†Œν”„νŠΈμ›¨μ–΄μ μœΌλ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€. μ–΄λ–€ 기초적인 λΆ€λ™μ†Œμˆ˜μ  계산은 μ™„λ£ŒκΉŒμ§€ λŒ€λž΅ 일 밀리 초 정도 걸릴 수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ, μ •μˆ˜μ—μ„œλ„ μ–΄λ–€ 칩듀은 ν•˜λ“œμ›¨μ–΄ κ³±μ…ˆμ„ 가지고 μžˆμ§€λ§Œ ν•˜λ“œμ›¨μ–΄ λ‚˜λˆ—μ…ˆμ΄ 없기도 ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 경우, μ •μˆ˜ λ‚˜λˆ—μ…ˆκ³Ό λ‚˜λ¨Έμ§€ 연산은 μ†Œν”„νŠΈμ›¨μ–΄μ μœΌλ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€ β€” λ§Œμ•½ ν•΄μ‹œ ν…Œμ΄λΈ”μ„ μ„κ³„ν•˜κ±°λ‚˜ λ§Žμ€ 계산이 ν•„μš”ν•˜λ‹€λ©΄ 생각해 보아야 ν•  κ²ƒμž…λ‹ˆλ‹€.

μ„±λŠ₯ μ˜ˆμ‹œ 숫자 λͺ‡ 개

우리의 λͺ‡ 가지 μ•„μ΄λ””μ–΄λΌ μ„λͺ…ν•˜κΈ° μœ„ν•΄, μ•½κ°„μ˜ 기초적인 행동듀에 λŒ€ν•΄ λŒ€λž΅μ μΈ μ‹€ν–‰μ‹œκ°„μ„ λ‚˜μ—΄ν•œ ν…Œμ΄λΈ”μ„ λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€. 이 값듀은 μ ˆλŒ€μ μΈ μˆ«μžκ°€ μ•„λ‹ˆλΌλŠ” 것을 μ£Όλͺ©ν•΄ μ£Όμ‹­μ‹œμ˜€: CPUμ‹œκ°„κ³Ό μ‹€μ œ ꡬ동 μ‹œκ°„μ˜ 쑰합이고, μ‹œμŠ€ν…œμ˜ μ„±λŠ₯ ν–₯상에 따라 λ³€ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 이 κ°’λ“€ 사이에 κ΄€κ³„λΌ μ μš©ν•΄ λ³΄λŠ” 것은 μ£Όλͺ©ν•  λ§Œν•œ κ°€μΉ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€ β€” μ˜ˆλΌ λ“€μ–΄, 멀버 λ³€μˆ˜λΌ λ”ν•˜λŠ” 것은 지역 λ³€μˆ˜λΌ λ”ν•˜λŠ” 것보닀 λŒ€λž΅ λ„λ°°κ°€ κ±Έλ¦½λ‹ˆλ‹€.

행동	μ‹œκ°„
지역 λ³€μˆ˜ λ”ν•˜κΈ°	1
멀버 λ³€μˆ˜ λ”ν•˜κΈ°	4
String.length() 호좜	5
빈 정적 λ„μ΄ν‹°λΈŒ λ©”μ†Œλ“œ 호좜	5
빈 정적 λ©”μ†Œλ“œ 호좜	12
빈 가상 λ©”μ†Œλ“œ 호좜	12.5
빈 μΈν„°νŽ˜μ΄μŠ€ λ©”μ†Œλ“œ 호좜	15
HashMap의 Iterator:next() 호좜	165
HashMap의 put() 호좜	600
XMLλ‘œλΆ€ν„° 1 View 객체화(Inflate)	22,000
1 TextViewλΌ λ‹΄μ€ 1 LinearLayout 객체화(Inflate)	25,000
6개의 View κ°μ²΄λΌ λ‹΄μ€ 1 LinearLayout 객체화(Inflate)	100,000
6개의 TextView κ°μ²΄λΌ λ‹΄μ€ 1 LinearLayout 객체화(Inflate)	135,000
빈 activity μ‹œμž‘	3,000,000
맺음 말

μž„λ² λ””λ“œ μ‹œμŠ€ν…œμ„ μœ„ν•΄ μ’‹κ³  효율적인 μ½”λ“œλΌ μž‘μ„±ν•˜λŠ” μ΅œμ„ μ˜ 방법은 μ—¬λŸ¬λΆ„μ΄ μž‘μ„±ν•˜λŠ” μ½”λ“œκ°€ μ‹€μ œλ‘œ 무엇을 ν•˜λŠ”μ§€ μ΄ν•΄ν•˜λŠ” 것 μž…λ‹ˆλ‹€. μ—¬λŸ¬λΆ„μ΄ μ •λ§λ‘œ λ°˜λ³΅μžλΌ ν• λ‹Ήν•˜κΈ°λΌ μ›ν•œλ‹€λ©΄, List에 ν–₯μƒλœ λ°˜λ³΅λ¬Έμ„ λ°˜λ“œμ‹œ μ‚¬μš©ν•˜μ‹­μ‹œμ˜€; λΆ€μ£Όμ˜ν•œ λΆ€μž‘μš©μ΄ μ•„λ‹Œ μ‹ μ€‘ν•œ 선택을 ν†΅ν•΄μ„œ λ§μž…λ‹ˆλ‹€.

μœ λΉ„λ¬΄ν™˜μž…λ‹ˆλ‹€! 무엇을 ν•˜λŠ”μ§€ μ•Œκ³  ν•˜μ„Έμš”! μ’‹μ•„ν•˜λŠ” 쒌우λͺ…을 여기에 λ„£μœΌμ„Έμš”, κ·ΈλŸ¬λ‚˜ μ–Έμ œλ‚˜ μ—¬λŸ¬λΆ„μ˜ μ½”λ“œκ°€ 무엇을 ν•˜λŠ”μ§€ 주의 깊게 μƒκ°ν•˜κ³ , μ†λ„λΌ λ†’μ΄λŠ” 방법을 찾도둝 κ²½κ³„ν•˜μ‹­μ‹œμ˜€.

7. 쀑얼거림

  1. fetchλ§žλŠ”λ°.. λΆˆλŸ¬μ˜€λŠ”κ±°
  2. λ¦¬νŽ™ν† λ§μ€ μƒˆλ‘œ λ§Œλ“œλŠ”κ²ƒλ³΄λ‹€ μ‰½κ΅¬λ‚˜.
  3. 근데 μ•ˆλ“œλ‘œμ΄λ“œλŠ” λ³΅μž‘ν•˜κ΅¬λ‚˜.. 아직 λ©€μ—ˆλ„
  4. μ–΄ν”Œμ΄ 쒋아지면 μ’‹μ•„μ§ˆμˆ˜λ‘ λ‚΄ λ¨Έλ¦¬λŠ” ν„°μ§€λŠ”κ΅°.
  5. μ•— 아이디어가 λ– μ˜¬λžμ–΄ S-Pen으둜 λ§Œλ“  μŠ€μΌ€μΉ˜ μ–΄ν”Œ. μ™Όμͺ½μ˜€λ₯Έμͺ½μ€ μ†κ°€λ½μœΌλ‘œν• λ•Œ 이동. OK
  6. μ•„μ•…................................ DB동기화 μ™œμ΄λž˜

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:28
Processing time 0.1315 sec