자바 의 반사 가 잘 안 돼 요.내성 을 시험 해 볼 까요?

8408 단어 자바반사내성
자바 의 내성 메커니즘 은 무엇 입 니까?
내성(Introspection)은 심리학 에서 심리학 기본 연구 방법 중의 하나 이다.내성 법 은 자기 관찰 법 이 라 고도 부른다.그것 은 내부 에서 발생 한 것 으로 우리 자신 이 의식 할 수 있 는 주관적 인 현상 이다.자신의 주관적 경험 과 변화 에 대한 관찰 이 라 고 할 수 있다.그 주관 성 때문에 내성 법 은 예로부터 심리학 계 의 오 랜 논쟁 이 되 었 다.그것 이 객관 적 인지,믿 을 만 한 지 에 대해 논쟁 하 다.또 내성 도 자기 반성 으로 볼 수 있 고 유가 가 강조 하 는 자기 사고 이기 도 하 다.이런 측면 에서 볼 때 이것 은 컴퓨터 분야,예 를 들 어 자바 내성 체제 와 cocoa 내성 체제 에 응용 할 수 있다.
자바 언어 내성(Introspector)은 자바 언어 가 Bean 류 속성,사건 에 대한 결 성 처리 방법 이다.예 를 들 어 클래스 A 에 속성 name 이 있 으 면 getName,setName 을 통 해 값 을 얻 거나 새로운 값 을 설정 할 수 있 습 니 다.getname/setName 을 통 해 name 속성 에 접근 하 는 것 이 기본 규칙 입 니 다.자바 에 서 는 특정한 속성 에 접근 하 는 getter/setter 방법 을 제공 합 니 다.이 API 를 통 해 이 규칙 을 알 필요 가 없 게 할 수 있 습 니 다.이 API 들 은 패키지 자바 beans 에 저 장 됩 니 다.일반적인 방법 은 클래스 Introspector 를 통 해 특정한 대상 의 BeanInfo 정 보 를 얻 은 다음 에 BeanInfo 를 통 해 속성 에 대한 설명 기(Property Descriptor)를 얻 는 것 입 니 다.이 속성 설명 기 를 통 해 특정한 속성 에 대응 하 는 getter/setter 방법 을 얻 을 수 있 습 니 다.그리고 우 리 는 반사 체 제 를 통 해 이 방법 을 호출 할 수 있 습 니 다.
이상 이 백과사전 의 해석 입 니 다.자바 의 내성 은 결국 자바 의 반사 로 이 루어 졌 다.그런데 왜 직접 반사 하지 않 고 내성 을 사용 해 야 합 니까?
내성 을 사용 하여 직접 반 사 를 사용 하면 파괴 류 의 포장 을 방지 할 수 있다.
우 리 는 나이 와 성인 여 부 를 포함 한 한 사람의 유형 을 정의 한다.연령 속성 을 수정 할 때 성인 여 부 를 동시에 수정 합 니 다.우 리 는 18 세 와 18 세 이상 이 성인 이 라 고 가정 한다.그렇지 않 으 면 미성년 이다.

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
class Person {
    /**
     * 18   
     */
    private static final int ADULT_AGE = 18;
    /**
     *   
     */
    private int     age;
    /**
     *     
     */
    private boolean adult;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
        this.adult = age >= ADULT_AGE;
    }
    public boolean isAdult() {
        return adult;
    }
    public String toString() {
        return MessageFormat.format("age:{0},adult:{1}", age, adult);
    }
}
/**
 * @author         https://le-yi.blog.csdn.net/
 */
public class Test {
    /**
     *           
     * @param o
     * @param fieldName
     * @param value
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void changeObjectFieldByReflection(Object o, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field field = o.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(o, value);
    }
    /**
     *           
     * @param o
     * @param fieldName
     * @param value
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void changeObjectFieldByIntrospector(Object o, String fieldName, Object value) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        PropertyDescriptor pd = new PropertyDescriptor(fieldName, o.getClass());
        pd.getWriteMethod().invoke(o, value);
    }
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        Person p = new Person();
        changeObjectFieldByReflection(p, "age", 20);
        System.out.println("            ,        :");
        System.out.println(p);
        changeObjectFieldByIntrospector(p, "age", 18);
        System.out.println("             :");
        System.out.println(p);
    }
}
在这里插入图片描述
반 사 는 속성 을 직접 수정 하기 때문에 클래스 에 포 장 된 논리(20 세 는 성인 이 아니다)를 파괴 한 것 을 볼 수 있다.
한편,내성 은 속성 을 수정 하기 때문에 set 방법 을 호출 했다.즉,정상 적 인 수정 대상 속성 과 같은 방법 을 호출 했 기 때문에 이러한 패 키 징 성 은 파괴 되 지 않 는 다.
물론 내성 의 본질 도 반사 이기 때문에 반 사 를 밀봉 했다 고 할 수 있 습 니 다.그래서 만약 에 반사 용이 정확 하고 안전 하 다 면 우 리 는 속성 명 에 따라 해당 하 는 set 와 get 방법 을 얻 은 다음 에 호출 할 수 있 습 니 다.그러나 이런 상황 에서 내성 에서 사용 하 는 것 이 더욱 편리 합 니 다.왜냐하면 바퀴 를 중복 발명 할 필요 가 없 기 때 문 입 니 다.원형 바퀴 는 이미 여러 해 동안 지혜 의 결정 이 되 었 다.
그렇다면 문제 가 생 겼 습 니 다.내성 이 set 와 get 방법 을 호출 하 는 것 인 데 저 는 왜 set 와 get 방법 을 직접 호출 하지 않 고 내성 을 사용 해 야 합 니까?
내성 을 사용 해도 통용 되 는 도 구 를 쓸 수 있다.
내성 에서 동태 적 으로 정 보 를 얻 을 수 있 으 니 반사 와 마찬가지 로 유 니 버 설 도구 나 프레임 워 크 를 실현 할 수 있 습 니 다.우 리 는 여기에서 임의의 유형의 두 대상 의 속성 값 을 복사 할 수 있 는 도구 방법 을 실현 한다.

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
class Person {
    /**
     * 18   
     */
    private static final int ADULT_AGE = 18;
    /**
     *   
     */
    private final String  name;
    /**
     *   
     */
    private       int     height;
    /**
     *   
     */
    private       int     age;
    /**
     *     
     */
    private       boolean adult;
    public Person(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
        this.adult = age >= ADULT_AGE;
    }
    public boolean isAdult() {
        return adult;
    }
    public String toString() {
        return MessageFormat.format("name:{0},height:{1},age:{2},adult:{3}", name, height, age, adult);
    }
}
/**
 * @author         https://le-yi.blog.csdn.net/
 */
public class Test {
    /**
     *  orig         dest      
     * @param dest
     * @param orig
     * @param <T>
     * @throws IntrospectionException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static <T> void copyProperties(T dest, T orig) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        BeanInfo beanInfo = Introspector.getBeanInfo(orig.getClass());
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            Method rm = pd.getReadMethod();
            Method wm = pd.getWriteMethod();
            if (rm != null
                && wm != null) {
                Object value = rm.invoke(orig);
                wm.invoke(dest, value);
            }
        }
    }
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        Person p2 = new Person("    ");
        p2.setAge(18);
        p2.setHeight(180);
        System.out.println(p2);
        Person p1 = new Person("    ");
        System.out.println(p1);
        System.out.println("                     :");
        copyProperties(p1, p2);
        System.out.println(p1);
    }
}
在这里插入图片描述
이름 이 복사 되 지 않 았 고 다른 속성 치가 순조롭게 복사 되 었 음 을 알 수 있다.이것 도 우리 가 바 라 는 결과 다.
내성 은 이러한 패 키 징 성 을 잘 확보 하 는 동시에 대상 속성 을 동적 으로 얻 고 대상 속성 을 동적 으로 수정 하 는 능력 도 가진다.
총결산
반사 와 마찬가지 로 일반적인 프로그램 도 내성 적 인 코드 를 쓰 지 못 할 수도 있다.그러나 apache 의 beanutils 와 같은 편리 한 도 구 는 반사 도 내성 도 없 으 면 어떻게 실현 해 야 할 지 정말 생각 나 지 않 습 니 다.설령 영원히 내성 을 사용 할 필요 가 없다 하 더 라 도,메커니즘 을 이해 하 는 것 은 우리 에 게 막대 한 이점 을 가지 고 있다.
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!

좋은 웹페이지 즐겨찾기