자바 반사 메커니즘 (3): 대상의 개인 속성과 방법을 호출합니다.

11629 단어
1. 반사 호출 클래스의 방법
정상적인 상황에서 클래스의 대상을 얻은 후에 우리는 클래스의 방법을 직접 호출할 수 있다. 만약에 호출하려면 호출할 방법이 무엇인지 분명히 알아야 한다. 그리고 클래스의 getMethod 방법을 통해 Method 대상을 얻을 수 있다.
public Method getMethod(String name,
                        Class>... parameterTypes)
                 throws NoSuchMethodException,
                        SecurityException

Method 대상을 가져오면 이 대상을 통해 방법을 실행할 수 있지만, 방법이 호출될 때, 방법의 매개 변수 문제와 관련이 있기 때문에 getMethod () 를 통해 얻을 때 매개 변수 형식을 설정해야 합니다.
package org.chen.yuan.reflect;
interface China{	//  China 
	public static final String NATIONAL = "China" ;	//  
	public static final String AUTHOR = " " ;	//  
	public void sayChina() ;		//  , 
	public String sayHello(String name,int age) ;	//  , 
}
public class Person implements China{
	private String name ;
	private int age ;
	public Person(){	//  
	}
	public Person(String name){
		this.name = name ;	//  name 
	}
	public Person(String name,int age){
		this(name) ;
		this.age = age ;
	}
	public void sayChina(){	//  
		System.out.println(" :" + AUTHOR + ", :" + NATIONAL) ;
	}
	public String sayHello(String name,int age){
		return name + ", ! :" + age + " !" ;
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
};

매개 변수가 없는 sayChina () 방법을 호출합니다.
호출 방법을 실행하려면 Method의 invoke 방법을 통해 다음을 수행해야 합니다.
public Object invoke(Object obj,
                     Object... args)
              throws IllegalAccessException,
                     IllegalArgumentException,
                     InvocationTargetException

예 1: (참조가 없는 메서드 호출)
package org.chen.yuan.reflect;
interface China{	//  China 
	public static final String NATIONAL = "China" ;	//  
	public static final String AUTHOR = " " ;	//  
	public void sayChina() ;		//  , 
	public String sayHello(String name,int age) ;	//  , 
}
public class Person implements China{
	private String name ;
	private int age ;
	public Person(){	//  
	}
	public Person(String name){
		this.name = name ;	//  name 
	}
	public Person(String name,int age){
		this(name) ;
		this.age = age ;
	}
	public void sayChina(){	//  
		System.out.println(" :" + AUTHOR + ", :" + NATIONAL) ;
	}
	public String sayHello(String name,int age){
		return name + ", ! :" + age + " !" ;
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
};

우리는 페르슨에 있다.java 클래스에서 무참한 방법say China와 파라미터가 있는 방법say Hello를 정의했습니다. 다음은 파라미터가 없는 방법을 호출합니다.
package org.chen.yuan.reflect;

import java.lang.reflect.Method;

public class InvokeSyaChinaDemo
{
    public static void main(String[] args)
    {
        Class> c1 = null;
        try
        {
            c1 = Class.forName("org.chen.yuan.reflect.Person");
            Method met = c1.getMethod("sayChina");
            met.invoke(c1.newInstance());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

국적: 차이나
이러한 반사 방식을 통해 우리는 Person 클래스의 방법을 순조롭게 호출할 수 있음을 알 수 있다.그러면 만약에 우리가 파라미터를 포함하는 방법인sayHello를 호출하려면 어떻게 해야 하나요?
만약 방법에 파라미터가 존재한다면 반드시 파라미터의 유형과 내용을 설정해야 한다고 상상할 수 있다.
public class InvokeSayHelloDemo
{

    public static void main(String[] args) throws Exception
    {
        Class> c1 = null;
        c1 = Class.forName("org.chen.yuan.reflect.Person");
        Method met = c1.getMethod("sayHello", String.class, int.class);
        String result = (String) met.invoke(c1.newInstance(), " ", 25);
        System.out.println(result);
    }

}

수출:침연,안녕하세요!나 올해 25살이야!
2. 반사 호출 클래스의setter 및 Getter 방법을 통해
setter와 Getter 방법은 클래스 속성에 접근하는 표준 방법입니다. 만약에 하나의 클래스의 속성이 봉인되면 setter와 Getter 방법을 통해 설정하고 얻어야 합니다. 실제로 이 방법의 조작이 이렇게 규정된 이유는 반사 메커니즘이 지원할 수 있기 때문입니다.
반사를 통해setter와getter 방법을 호출할 수 있습니다.
package org.chen.yuan.reflect;

import java.lang.reflect.Method;

public class InvokeSetGetDemo
{

    public static void main(String[] args) throws Exception
    {
        Class> c1 = null;
        Object obj = null;

        c1 = Class.forName("org.chen.yuan.reflect.Person");
        obj = c1.newInstance();

        setter(obj, "name", " ", String.class);
        getter(obj, "name");

        setter(obj, "age", 25, int.class);
        getter(obj, "age");
    }

    /**
     * @param obj  
     * @param att  
     * @param value  
     * @param type  
     */
    public static void setter(Object obj, String att, Object value, Class> type)
    {
        try
        {
            Method met = obj.getClass().getMethod("set" + initStr(att), type);
            met.invoke(obj, value);

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * @param obj  
     * @param att  
     */
    public static void getter(Object obj, String att) throws Exception
    {
        Method met = obj.getClass().getMethod("get" + initStr(att));
        System.out.println(met.invoke(obj));
    }

    /**
     *  
     * 
     * @param old
     * @return
     */
    public static String initStr(String old)
    {
        String newStr = old.substring(0, 1).toUpperCase() + old.substring(1);
        return newStr;
    }
}

3. 반사로 속성 호출
클래스의 속성을 조작하려면 Field를 통해서도 할 수 있으며 setter와 Getter를 통해 번거롭게 할 필요가 없습니다.클래스에서 클래스의 Field를 가져오는 방법:
1) 클래스에서 공통 속성 얻기
public Field getField(String name)
               throws NoSuchFieldException,
                      SecurityException

2) 이 클래스 속성 획득
public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException

Field 클래스에서는 속성 컨텐트를 가져오고 설정하는 방법을 제공합니다.
1) 속성 컨텐트 가져오기
public Object get(Object obj)
           throws IllegalArgumentException,
                  IllegalAccessException

2) 속성 내용 설정
public void set(Object obj,
                Object value)
         throws IllegalArgumentException,
                IllegalAccessException

또한 클래스의 개인 속성에 액세스할 때 이 속성을 외부에 보여야 한다는 점에 유의해야 합니다.
public void setAccessible(boolean flag)
                   throws SecurityException

이 메서드는 Field의 상위 클래스를 상속합니다.
java.lang.reflect

Class AccessibleObject


이 방법의 매개 변수 내용을true로 설정하면 됩니다.
public class InvokeFieldDemo
{
    public static void main(String args[]) throws Exception
    {
        Class> c1 = null;
        Object obj = null;
        c1 = Class.forName("org.chen.yuan.reflect.Person"); //  Class 
        obj = c1.newInstance();
        Field nameField = null;
        Field ageField = null;
        nameField = c1.getDeclaredField("name"); //  name 
        ageField = c1.getDeclaredField("age"); //  name 
        nameField.setAccessible(true); //  
        ageField.setAccessible(true); //  
        nameField.set(obj, " "); //  name 
        ageField.set(obj, 25); //  age 
        System.out.println(" :" + nameField.get(obj));
        System.out.println(" :" + ageField.get(obj));
    }
};

출력:
이름:침연나이
이를 통해 알 수 있듯이, 조작 속성은 반드시 setter와 Getter 방법의 지원이 필요하지는 않지만, 프로그램의 안전성을 확보하기 위해서는 setter와 Getter 방법을 통해 속성을 조작하는 것이 가장 좋다.
4. 반사 조작을 통한 수조
반사 메커니즘은 클래스에만 사용할 수 있는 것이 아니라 임의의 인용 데이터 형식에도 적용될 수 있다. 물론 이것은 그룹을 포함하고 그룹은 Array 클래스로 완성된다.
Class 클래스에는 다음 메서드가 있습니다.
public Class> getComponentType()

배열에 지정된 아래 첨자의 컨텐트는 Array 클래스에서 다음과 같습니다.
public static Object get(Object array,
                         int index)
                  throws IllegalArgumentException,
                         ArrayIndexOutOfBoundsException

Array 클래스에서 수정된 내용:
public static void set(Object array,
                       int index,
                       Object value)
                throws IllegalArgumentException,
                       ArrayIndexOutOfBoundsException

Array 클래스에서 새 배열 열기
public static Object newInstance(Class> componentType,
                                 int... dimensions)
                          throws IllegalArgumentException,
                                 NegativeArraySizeException

배열 정보를 가져오고 내용을 수정하려면 다음과 같이 하십시오.
package org.chen.yuan.reflect;
import java.lang.reflect.Array ;
public class ClassArrayDemo{
	public static void main(String args[]) throws Exception{
		int temp[] = {1,2,3} ;//  
		Class> c = temp.getClass().getComponentType() ;	//  Class 
		System.out.println(" :" + c.getName()) ;	//  
		System.out.println(" :" + Array.getLength(temp)) ;
		System.out.println(" :" + Array.get(temp,0)) ;
		Array.set(temp,0,6) ;
		System.out.println(" :" + Array.get(temp,0)) ;
	}
};

출력:
유형: int 길이: 3 첫 번째 내용: 1 첫 번째 내용: 6
수조를 수정하는 과정은 사실상 새로운 수조를 만드는 과정이기 때문에 낡은 수조의 내용을 새로운 수조로 복사해야 한다.
package org.chen.yuan.reflect;

import java.lang.reflect.Array;

public class ChangeArrayDemo
{
    public static void main(String args[]) throws Exception
    {
        int temp[] = {1, 2, 3};//  
        int newTemp[] = (int[]) arrayInc(temp, 5); //  5
        print(newTemp);
        System.out.println("
-------------------------"); String t[] = {"chenyuan", "wuqing", "lengxue"}; String nt[] = (String[]) arrayInc(t, 8); print(nt); } public static Object arrayInc(Object obj, int len) { Class> c = obj.getClass(); Class> arr = c.getComponentType(); // Object newO = Array.newInstance(arr, len); // int co = Array.getLength(obj); System.arraycopy(obj, 0, newO, 0, co); // return newO; } public static void print(Object obj) { // Class> c = obj.getClass(); if (!c.isArray()) { // return; } Class> arr = c.getComponentType(); System.out.println(arr.getName() + " :" + Array.getLength(obj)); // for (int i = 0; i < Array.getLength(obj); i++) { System.out.print(Array.get(obj, i) + "、"); // Array } } };

출력:
nt수 그룹의 길이는 51, 2, 3, 0, 0, ---------------------------------java입니다.String 그룹의 길이는 8chenyuan,wuqing,lengxue,null,null,null,null,null,null,
전재 대상:https://www.cnblogs.com/hehe520/p/6330010.html

좋은 웹페이지 즐겨찾기