안녕하세요 어제 뻘짓 좀 하다가 뻘짓 내용좀 초보 개발자님이 공유 하자고 해서 이렇게 공유 합니다. ㅎㅎ

뻘짓 내용 : http://www.androidpub.com/?mid=android_dev_qna&page=2&document_srl=1375814


앞으로 abstract 형에 대한 고찰도 필요 할거 같은데요..

이부분에 대해서 자알? 알고 계신분은 댓글좀 팍팍 주세욤 ㅎㅎ


특히 제가 추천을 팍팍 날려줬던 분들과.. 초보 개발자님도 테스트에 관해서 좋은 의견이 있으시면 우선순위로

답변을 달 수 있는 권한을 드리도록 하겠습니다. ㅎㅎ


아래 내용은 http://blog.naver.com/lowmans/100124202116 에서 퍼 왔습니다. 


http://blog.naver.com/lowmans 에서 참고한 내용으로 Android 에서 Refection 을 테스트 함


첨부파일 안에 doc 문서로 해당 링크 자료를 써머리 하였으니 참고 바람..


package : lowmans.test.reflection 

main class : lowmans.test.refleciton.ReflecitonTest

test class : lowmans.test.reflection.Test



같은 패키지에 Test Class 를 만들고 메인 Activity에서 테스트 하였음


테스트 내용

1. DumpMethods : Class 내 존재하는 method Search

2. Finding Out About Methods of a Class : DumpMethods 와 내용이 같으나 print 방법이 조금 틀림

3. Obtaining Information About Constructors : Class 내 존재 하는 Constructors Search

4. Finding Out About Class Fields : Class 내 존재 하는Fields Search

5. Invoking Methods by Name : Class 내 존재하는 Method를 이름으로 얻어와서 실행

6. Creating New Objects : Class Instance 를 각각 Constructor Type 맞게 생성

7. Changing Values of Fields : Class 내 Member 변수를 get , set 형식의 방법이 아닌 직접 억세스 하여 사용

8. Using Arrays: Class 배열 형태로 Instance (1차원 배열 , 다차원 배열)


===========================================================================================================================================

package lowmans.test.reflection;


import android.content.Context;


public class Test {


private int i, j;

private String string;

private Context context;


public Test() {

i = -1;

j = -1;

string = "contstuctor:Test()";

context = null;

}


public Test(int i, int j) {

this.i = i;

this.j = j;

string = "contstuctor:Test(int i, int j)";

context = null;

}


public Test(String string, Context context) {

this.i = -2;

this.j = -2;

this.string = string;

this.context = context;

}


public void showClass() {

System.out.println("[Test Class] showClass = " + Test.class);

}


private void showMemberFields() {

System.out.println("[Test Class] i = " + i + ", j = " + j + ", string = " + string + ", context = " + context);

}


protected void setInitialize(int i , int j , String string , Context context){

this.i = i;

this.j = j;

this.string = string;

this.context = context;

}

}

===========================================================================================================================================
package lowmans.test.reflection;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ReflectionTest extends Activity implements OnClickListener {
private final static String TAG = "ReflectionTest";
private Context context;
private final int BUTTON_SIZE = 8;
private final int BUTTON_ID = R.id.btn1;
private final String CLASS_NAME = "lowmans.test.reflection.Test";
private Button btn[];

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = getBaseContext();
btn = new Button[BUTTON_SIZE];

for (int i = 0; i < BUTTON_SIZE; i++) {
btn[i] = (Button) findViewById(BUTTON_ID + i);
btn[i].setOnClickListener(this);
}
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1: // DumpMethods
System.out.println("************* DumpMethods *************");
try {
Class c = Class.forName(CLASS_NAME);
// getDeclaredMethods -> public,protected,private Method 를 모두 검색
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;
case R.id.btn2: // Finding Out About Methods of a Class
System.out.println("************* Finding Out About Methods of a Class *************");
try {
Class cls = Class.forName(CLASS_NAME);

Method methlist[] = cls.getDeclaredMethods();
for (int i = 0; i < methlist.length; i++) {
Method m = methlist[i];
System.out.println("name  = " + m.getName());
System.out.println("getDeclaringClass class = " + m.getDeclaringClass());
Class pvec[] = m.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println(" param #" + j + " " + pvec[j]);
Class evec[] = m.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("return type = " + m.getReturnType());
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn3: // Obtaining Information About Constructors
System.out.println("************* Obtaining Information About Constructors *************");
try {
Class cls = Class.forName(CLASS_NAME);

// Class 내 존재하는 Constructor를 search 한다.
// public , private 와 같은 속성은 보여주지 않는다.
Constructor ctorlist[] = cls.getDeclaredConstructors();
for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name = " + ct.getName());
System.out.println("decl class = " + ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn4: // Finding Out About Class Fields
System.out.println("************* Finding Out About Class Fields *************");
try {
Class cls = Class.forName(CLASS_NAME);

// Class 내 존재하는 MemberField를 search 한다.
// public , private 와 같은 속성을 알 수 있다.
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name = " + fld.getName());
System.out.println("decl class = " + fld.getDeclaringClass());
System.out.println("type= " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn5: // Invoking Methods by Name
System.out.println("************* Invoking Methods by Name *************");
try {
Class cls = Class.forName(CLASS_NAME);
// lowmans.test.reflection.Test instanceClass = (Test) cls.newInstance();
Test instanceClass = (Test) cls.newInstance();

// getDeclaredMethod -> Class 내 Member Method 를 Search 한다.
// public , protected , private Method 모두 알 수 있다
// 접근 권한이 적은 private 와 같은 경우 isAccessible 를 확인하여 가용할 수 있는
// 상태로 변환해야 한다. isAccessible is false -> setAccessible(true);

Method showClass = cls.getDeclaredMethod("showClass", null);
showClass.invoke(instanceClass, new Object[] {});

// Member Method 중 Method 인자값(parameter) 으로 void.class or Void.TYPE 일경우
// 예> private void showMemberFields(){} 같은 경우 아래와 같이 인자값을 맞춰주면 된다
// 잘못된 예>
// cls.getDeclaredMethod("showMemberFields", new Class[] {});
// cls.getDeclaredMethod("showMemberFields", new Class[] {void.class});
// cls.getDeclaredMethod("showMemberFields", new Class[] {Void.TYPE});
Method showMemberFields = cls.getDeclaredMethod("showMemberFields", null);
if (!showMemberFields.isAccessible()) {
showMemberFields.setAccessible(true);
}

// Method 인자값(parameter)이 void type 이므로 new Object[] {} 으로 null 처리를 대행한다
showMemberFields.invoke(instanceClass, new Object[] {});

// Method 의 인자값이 있을경우 primitive parameter type이 있으니 유의 하길 바란다.
// java.lang.Boolean.TYPE
// java.lang.Character.TYPE
// java.lang.Byte.TYPE
// java.lang.Short.TYPE
// java.lang.Integer.TYPE
// java.lang.Long.TYPE
// java.lang.Float.TYPE
// java.lang.Double.TYPE
// java.lang.Void.TYPE
// 타입은 Object.class 로 대체 가능하다.
// Class c = int.class; or Class c = Integer.TYPE; 어떤것을 사용하여도 무관하다

Method setInitialize = cls.getDeclaredMethod("setInitialize", new Class[] { Integer.TYPE, Integer.TYPE, String.class,
Context.class });
if (!setInitialize.isAccessible()) {
setInitialize.setAccessible(true);
}
// 자료형의 경우  wrapper for the primitive type 형의 wrapper class 를 사용하여야 한다.
// 예>100 -> Integer(100)
setInitialize.invoke(instanceClass,
new Object[] { new Integer(100), new Integer(200), new String("this is test"), null });

} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn6: // Creating New Objects
System.out.println("************* Creating New Objects *************");
try {
Class cls1 = Class.forName(CLASS_NAME);
Test test1 = (Test) cls1.newInstance();
// lowmans.test.relflection.Test 를 이름으로 검색하여 얻어온 객체 cls1 을
// instance 시켜서 만든 test1객체를 확인 하기 위해 showMemberFields 을 호출 하였다.
Method showMemberFields1 = cls1.getDeclaredMethod("showMemberFields", null);
if (!showMemberFields1.isAccessible()) {
showMemberFields1.setAccessible(true);
}
showMemberFields1.invoke(test1, new Object[] {});

// 생성자 타입이 public 이어야 하며  public 선언이 없는 경우 자동으로 private 형으로 생성자가 만들어진다.
// 생성자의 경우 getDeclaredMethod 으로 스캔이 불가능 하므로 반듯이 public 형에 한해 getConstructor
// 사용이 제한되어 있음을 유의 하자
Class cls2 = Class.forName(CLASS_NAME);
Constructor ct2 = cls2.getConstructor(new Class[] { int.class, Integer.TYPE });
Test test2 = (Test) ct2.newInstance(new Object[] { new Integer(123), new Integer(456) });

Method showMemberFields2 = cls2.getDeclaredMethod("showMemberFields", null);
if (!showMemberFields2.isAccessible()) {
showMemberFields2.setAccessible(true);
}
showMemberFields2.invoke(test2, new Object[] {});

Class cls3 = Class.forName(CLASS_NAME);
Constructor ct3 = cls3.getConstructor(new Class[] { String.class, Context.class });
cls3.getConstructors();
Test test3 = (Test) ct3.newInstance(new Object[] { new String("Constructor"), context });

Method showMemberFields3 = cls3.getDeclaredMethod("showMemberFields", null);
if (!showMemberFields3.isAccessible()) {
showMemberFields3.setAccessible(true);
}
showMemberFields3.invoke(test3, new Object[] {});

} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn7: // Changing Values of Fields
System.out.println("************* Changing Values of Fields *************");
try {
Class cls = Class.forName(CLASS_NAME);
Test instance = (Test) cls.newInstance();

// Member Method 를  Search 할 수 있듯이 Member Field도 같은 방법으로 사용가능하다
// 속성정보가 publc , private 형으로 구분 되어 있으니 접근 권한에 대한 속성정보 확인하여 변경 하도록 한다.
Field fld1 = cls.getDeclaredField("i");
Field fld2 = cls.getDeclaredField("j");
Field fld3 = cls.getDeclaredField("string");
Field fld4 = cls.getDeclaredField("context");

//Member Method 사용방법과 같다
if (!fld1.isAccessible()) {
fld1.setAccessible(true);
}
if (!fld2.isAccessible()) {
fld2.setAccessible(true);
}
if (!fld3.isAccessible()) {
fld3.setAccessible(true);
}
if (!fld4.isAccessible()) {
fld4.setAccessible(true);
}

fld1.setInt(instance, 11111);
fld2.setInt(instance, 22222);
fld3.set(instance, "Changing Values of Fields");
fld4.set(instance, context);

Method showMemberFields = cls.getDeclaredMethod("showMemberFields", null);
if (!showMemberFields.isAccessible()) {
showMemberFields.setAccessible(true);
}
showMemberFields.invoke(instance, new Object[] {});

} catch (Throwable e) {
System.err.println(e);
}
System.out.println("*********************************************************************");
break;

case R.id.btn8: // Using Arrays
System.out.println("*************Using Arrays *************");

// Class를 배열로 만들어 사용 한다.
// single arr
try {
Class cls = Class.forName("java.lang.String");
Object arr = Array.newInstance(cls, 10);
Array.set(arr, 5, "this is a test");
String s = (String) Array.get(arr, 5);
System.out.println(s);
} catch (Throwable e) {
System.err.println(e);
}

// multi arr
int dims[] = new int[] { 5, 10, 15 };
Object arr = Array.newInstance(Integer.TYPE, dims);

Object arrobj = Array.get(arr, 3);
Class cls = arrobj.getClass().getComponentType();
System.out.println(cls);
arrobj = Array.get(arrobj, 5);
Array.setInt(arrobj, 10, 37);

int arrcast[][][] = (int[][][]) arr;
System.out.println(arrcast[3][5][10]);
System.out.println("*********************************************************************");
break;

}

}
}
===========================================================================================================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/btn1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="DumpMethods" />
<Button
android:id="@+id/btn2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Finding Out About Methods of a Class" />
<Button
android:id="@+id/btn3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Obtaining Information About Constructors" />
<Button
android:id="@+id/btn4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text= "Finding Out About Class Fields" />
<Button
android:id="@+id/btn5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Invoking Methods by Name" />
<Button
android:id="@+id/btn6"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Creating New Objects" />
<Button
android:id="@+id/btn7"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Changing Values of Fields" />
<Button
android:id="@+id/btn8"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Using Arrays" />
</LinearLayout>