자바 의 매 거,주해 와 반사(2)

반사
반사 란 무엇 입 니까?
반사 란 프로그램 이 실행 되 는 동안 Reflection Api 를 통 해 모든 종류의 내부 정 보 를 얻 을 수 있 고,임의의 종류의 방법 과 속성 을 직접 조작 할 수 있 는 방법 을 말한다.반 사 는 동적 언어의 관건 으로 여 겨 진다.

//           
    @Test
    public void Test1() {
        //  Person    
        Person person = new Person("name", 78);
        //               
        person.setAge(20);
        System.out.println(person.toString());
        person.show();
        // Person    ,                 
    }
    //           
    @Test
    public void Test2() throws Exception {
        //      Person    
        Class classPerson = Person.class;
        Constructor constructor = classPerson.getConstructor(String.class, int.class);
        Object object = constructor.newInstance("Tom", 13);
        Person person = (Person) object;
        System.out.println(person.toString());
        //      Person        
        Field name = classPerson.getField("name");
        name.set(person, "Jack");
        System.out.println(person.toString());
        //   
        Method show = classPerson.getDeclaredMethod("show");
        show.invoke(person);
        //         
        Constructor constructor1 = classPerson.getDeclaredConstructor(String.class);
        constructor1.setAccessible(true);
        Person person1 = (Person) constructor1.newInstance("Marry");
        System.out.println(person1);
        //       
        Method showNation = classPerson.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        showNation.invoke(person1, "  ");
    }
결과:
미사 용 반사
在这里插入图片描述
사용 반사:
在这里插入图片描述
Person 류

package reflection;
/**
 * user:ypc;
 * date:2021-06-20;
 * time: 13:55;
 */
public class Person {
    public String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Person() {
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        this.age = age;
        this.name = name;
    }
    private Person(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public void show() {
        System.out.println("I am a person");
    }
    private String showNation(String nation) {
        return nation;
    }

}
반사 적 용도
1.일상적인 제3자 응용 개발 과정 에서 특정한 유형의 특정한 구성원 변수,방법 또는 속성 이 개인 적 이거 나 시스템 응용 에 만 개방 되 는 경우 가 많다.이때 자바 의 반사 체 제 를 이용 하여 반 사 를 통 해 필요 한 개인 구성원 이나 방법 을 얻 을 수 있다.
2.반사 의 가장 중요 한 용 도 는 바로 각종 유 니 버 설 프레임 워 크 를 개발 하 는 것 입 니 다.예 를 들 어 spring 에서 우 리 는 모든 종류의 Bean 을 spring 용기 관리 에 맡 깁 니 다.XML 설정 Bean 이 든 주해 설정 이 든 용기 에서 Bean 을 가 져 와 주입 에 의존 할 때 용 기 는 설정 을 읽 습 니 다.설정 에서 주 는 것 은 바로 유형의 정보 입 니 다.spring 은 이러한 정보 에 따라 Bean 을 만들어 야 합 니 다.spring 은 이러한 종 류 를 동적 으로 만 듭 니 다.
자바 프로그램의 많은 대상 이 실 행 될 때 두 가지 유형 이 나타 납 니 다.실 행 될 때 유형(RTTI)과 컴 파일 할 때 유형,예 를 들 어 Person p=new Student();이 코드 에서 p 는 컴 파일 할 때 Person 형식 이 고 실행 할 때 Student 형식 입 니 다.프로그램 은 실행 할 때 대상 과 클래스 의 진실 한 정 보 를 발견 해 야 한다.반사 프로그램 을 사용 하면 이 대상 과 클래스 가 어떤 종류 에 속 하 는 지 판단 할 수 있다.
클래스 가 불 러 오 면 쌓 인 구역 에 Class 대상 이 생 깁 니 다.이 대상 은 이러한 종류의 모든 구조 정 보 를 포함 합 니 다.우 리 는 이 대상 을 통 해 이런 종류의 모든 정 보 를 볼 수 있다.
이 대상 은 거울 과 같 아서 이 거울 을 통 해 이런 모든 정보 구 조 를 볼 수 있다.반사 라 고 합 니 다.
정상 적 인 방식:가 져 올 패키지 의 이름 을 도입 합 니 다.->new 를 통 해 예화 합 니 다.->예화 대상 을 얻 습 니 다.
반사 방식:실례 화 대상->getClass()방법->을 통 해 완전한 패키지 클래스 의 이름 을 얻 을 수 있 습 니 다
반사 의 구체 적 인 작용
4.567917.운행 할 때 임의의 대상 이 속 한 종 류 를 판단 한다4.567917.운행 할 때 임의의 유형의 대상 을 구성한다4.567917.실행 할 때 임의의 유형의 구성원 변수 와 방법 을 판단 한다
  • 실행 할 때 일반적인 정 보 를 얻 습 니 다
  • 4.567917.실행 할 때 임의의 유형의 구성원 변수 와 방법 을 호출 합 니 다
  • 운행 할 때 주 해 를 처리 합 니 다
  • 동적 에이전트 생 성
    반사의 주 API
    아 날로 그 용도
    4.567914.대표 클래스 의 실체,실행 중인 자바 응용 프로그램 에서 클래스 와 인 터 페 이 스 를 표시 합 니 다.
    대표 클래스 의 구성원 변수/클래스 의 속성
    대표 적 인 방법
    대표 적 인 구조 방법
    직접 new 방식 과 반 사 를 통 해 공공 구 조 를 직접 호출 할 수 있 는데 개발 할 때 어떤 것 을 사용 해 야 합 니까?
    제안:new 방식 으로 대상 을 만 듭 니 다.
    반 사 는 언제 사용 합 니까?
    반사 적 특성:동적.컴 파일 할 때 어떤 대상 을 만 들 지 모 를 때 반사 방식 으로 대상 을 만 들 수 있다 는 것 이다.예 를 들 어 백 엔 드 에 배 치 된 서버,전단 에서 들 려 올 때 로그 인 요청 을 하면 로그 인 에 대응 하 는 대상 을 만 듭 니 다.전단 에서 등록 에 대응 하 는 요청 이 들 어 오 면 로그 인 에 대응 하 는 대상 을 만 드 는 것 이 반 사 된 동적 특성 입 니 다.
    반사 적 인 메커니즘 과 포장 은 모순 되 지 않 습 니까?
    포장 은 너 에 게 조절 하지 말 라 고 말 하 는 것 이 고 반 사 는 조절 할 수 있다.
    클래스 클래스
    Object 클래스 에서 다음 과 같은 방법 을 정 의 했 습 니 다.이 방법 은 모든 하위 클래스 에 의 해 계 승 됩 니 다.
    
    public final Class getClass()
    
    이상 의 방법 으로 값 을 되 돌려 주 는 유형 은 클래스 클래스 입 니 다.이것 은 자바 반사 의 원천 입 니 다.실제로 반사 라 는 것 은 프로그램의 운행 결 과 를 보면 이해 하기 쉽 습 니 다.즉,대상 을 통 해 클래스 의 이름 을 반사 적 으로 구 할 수 있 습 니 다.
    대상 이 반 사 를 사용 한 후에 얻 을 수 있 는 정보:특정한 유형의 속성,방법 과 구조 기,특정한 유형 이 도대체 어떤 인 터 페 이 스 를 실현 하 는 지.각 클래스 에 대해 JRE 는 변 하지 않 는 Class 형식의 대상 을 보존 합 니 다.하나의 Class 대상 은 특정한 구조(class/interface/enum/annotation/primitive type/void/[])에 대한 정 보 를 포함 하고 있 습 니 다.즉,이러한 유형 은 class 대상 이 있 을 수 있 습 니 다.class 구성원 내부 류,정적 내부 류,국부 내부 류,익명 내부 류,인터페이스,배열,매 거 진,주석,기본 적 인 데이터 유형,void 등 이 있 습 니 다.
    주의:
    Class 자체 도 클래스 입 니 다.
    Class 대상 은 시스템 에서 만 대상 을 만 들 수 있 습 니 다.
    불 러 오 는 클래스 는 JVM 에서 하나의 Class 인 스 턴 스 만 있 습 니 다.
    Class 대상 은 JVM 에 불 러 온.class 파일 에 대응 합 니 다.
    모든 종류의 인 스 턴 스 는 자신 이 어떤 Class 인 스 턴 스 로 생 성 되 었 는 지 기억 합 니 다.
    클래스 를 통 해 클래스 에 불 러 오 는 모든 구 조 를 완전 하 게 얻 을 수 있 습 니 다.
    Class 클래스 는 Reflection 의 근원 입 니 다.동적 으로 불 러 오고 실행 하고 싶 은 모든 클래스 에 대해 해당 하 는 Class 대상 을 먼저 얻어 야만 계속 할 수 있 습 니 다.
    java.lang.Class 에 대한 이해:
    클래스 로 딩 과정:
    프로그램 은 javac.exe 명령 을 통 해 하나 이상 의 바이트 파일 을 생 성 합 니 다.이 어 자바.exe 명령 을 사용 하여 어떤 바이트 파일 에 대해 실행 을 설명 합 니 다.메모리 에 바이트 코드 파일 을 불 러 옵 니 다.이 과정 을 클래스 로 불 러 옵 니 다.메모리 에 불 러 온 클래스 를 실행 클래스 라 고 합 니 다.이 실행 클래스 를 Class 의 인 스 턴 스 라 고 합 니 다.
    Class 인 스 턴 스 는 실행 중인 클래스 에 대응 합 니 다.메모리 에 불 러 오 는 실행 중인 클래스 는 캐 시 됩 니 다.이 시간 안에 실행 시 류 를 다른 방식 으로 가 져 올 수 있 습 니 다.
    Class 인 스 턴 스 를 가 져 오 는 네 가지 방식
    
        //     Class           
        @Test
        public void test3() throws ClassNotFoundException {
            //  1          :.class
            Class clazz1 = Person.class;
            System.out.println(clazz1);
            //  2             
            Person person = new Person();
            Class clazz2 = person.getClass();
            System.out.println(clazz2);
    
            //  3   Class      forName(       )
            Class clazz3 = Class.forName("reflection.Person");
            System.out.println(clazz3);
            //  4       :ClassLoader
            ClassLoader classLoader = ReflectionDemo1.class.getClassLoader();
            Class clazz4 = classLoader.loadClass("reflection.Person");
            System.out.println(clazz4);
            System.out.println(clazz1 == clazz2);
            System.out.println(clazz1 == clazz3);
            System.out.println(clazz1 == clazz4);
        }
    
    在这里插入图片描述
    반 사 를 통 해 실행 중인 클래스 의 대상 을 만 듭 니 다.
    
    package reflection;
    import org.junit.Test;
    import java.util.Random;
    /**
     * user:ypc;
     * date:2021-06-21;
     * time: 20:36;
     */
    public class NewInstanceDemo {
        @Test
        public void test1() throws IllegalAccessException, InstantiationException {
            Class<Person> personClass = Person.class;
            /*
            newInstance()             ,                     
             */
            Person person = personClass.newInstance();
            System.out.println(person);
        }
        @Test
        public void test2() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
            //               。                
            for (int i = 0; i < 100; i++) {
                int num = new Random().nextInt(3);
                String classPath = "";
                switch (num) {
                    case 0:
                        classPath = "java.util.Date";
                        break;
                    case 1:
                        classPath = "java.lang.Object";
                        break;
                    case 2:
                        classPath = "reflection.Person";
                        break;
                }
                Object object = getInstance(classPath);
                System.out.println(object);
            }
        }
        //          
        public Object getInstance(String classPath) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
            Class clazz = Class.forName(classPath);
            return clazz.newInstance();
        }
    }
    
    반사 로 실행 클래스 의 속성 및 권한 수정자,변수 이름,데이터 형식 가 져 오기
    
        @Test
        public void test1(){
            //getFields()             public   
            Class clazz = Person.class;
            Field[] fields = clazz.getFields();
            for (Field field: fields) {
                System.out.println(field);
            }
            System.out.println();
            //getDeclaredFields():            
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field field:declaredFields) {
                System.out.println(field);
            }
        }
    
    在这里插入图片描述
    
        //                 
        @Test
        public void test2(){
            Class clazz = Person.class;
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field field:declaredFields) {
                //     
                System.out.println(Modifier.toString(field.getModifiers())+"\t");
    
                //   
                System.out.println(field.getType()+"\t");
                //     
                System.out.println(field.getName()+"\t");
            }
        }
    
    在这里插入图片描述
    반 사 를 통 해 운행 시 클래스 의 방법 구조 와 내부 구 조 를 얻 을 수 있 습 니 다.
    
    package reflection2;
    import org.junit.Test;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    /**
     * user:ypc;
     * date:2021-06-22;
     * time: 13:32;
     */
    public class MethodDemo {
        @Test
        public void test1() {
            //                  public   
            Class clazz = Person.class;
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
            System.out.println();
            //             
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method method : declaredMethods) {
                System.out.println(method);
            }
        }
        //@xxx  
        //                    
        @Test
        public void test2() {
            Class clazz = Person.class;
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method method : declaredMethods) {
                //       
                Annotation[] annotations = method.getDeclaredAnnotations();
                for (Annotation annotation : annotations) {
                    System.out.print(annotation);
                }
                //        
                System.out.print(Modifier.toString(method.getModifiers()) + "\t");
                //        
                System.out.print(method.getReturnType().getName() + "\t");
                //   
                System.out.print(method.getName());
                System.out.print("(");
                //       
                Class[] parameterTypes = method.getParameterTypes();
                if (!(parameterTypes == null && parameterTypes.length == 0)) {
                    for (int i = 0; i < parameterTypes.length; i++) {
                        if (i == parameterTypes.length - 1) {
                            System.out.print(parameterTypes[i].getName() + " args__" + i);
                        } else {
                            System.out.print(parameterTypes[i].getName() + " args__" + i + ",");
                        }
                    }
                }
                System.out.print(")");
                //       
                Class[] exceptionTypes = method.getExceptionTypes();
                if (exceptionTypes.length != 0) {
                    System.out.print("throws");
                    for (int i = 0; i < exceptionTypes.length; i++) {
                        if (i == exceptionTypes.length - 1) {
                            System.out.print(exceptionTypes[i].getName());
                        } else {
                            System.out.print(exceptionTypes[i].getName() + ",");
                        }
                    }
                }
                System.out.println();
            }
        }
    }
    
    test1():
    在这里插入图片描述
    test2():
    在这里插入图片描述
    반 사 를 통 해 운행 시 클래스 의 구조 구 조 를 가 져 옵 니 다.
    
        @Test
        public void test1() {
            Class clazz = Person.class;
            //       public    
            Constructor[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
            System.out.println();
            //                 
            Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
            for (Constructor declaredConstructor : declaredConstructors) {
                System.out.println(declaredConstructor);
            }
        }
    
    在这里插入图片描述
    반 사 를 통 해 실행 중인 부류 의 부류 와 부류 의 범 형,주해,인터페이스,소재 패 키 지 를 가 져 옵 니 다.
    사용 한 가방,인터페이스,클래스,주석 등 을 반사 합 니 다.👇
    在这里插入图片描述
    
    package reflection2;
    /**
     * user:ypc;
     * date:2021-06-21;
     * time: 21:38;
     */
    public interface MyInterface {
        void info();
    }
    
    package reflection2;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import static java.lang.annotation.ElementType.*;
    
    @Target({TYPE, FIELD,CONSTRUCTOR,ANNOTATION_TYPE,PARAMETER,LOCAL_VARIABLE,METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
        String value() default "hello";
    }
    
    package reflection2;
    import java.io.Serializable;
    /**
     * user:ypc;
     * date:2021-06-21;
     * time: 21:13;
     */
    public class Creature<T> implements Serializable {
        private char gender;
        public double weight;
        private void breath(){
            System.out.println("creature breath");
        }
        public void eat(){
            System.out.println("creature eat");
        }
    }
    
    package reflection2;
    @MyAnnotation(value = "hi")
    public class Person extends Creature<String> implements Comparable, MyInterface {
        private String name;
        public int age;
        int id;
        Person() {
        }
        @MyAnnotation(value = "a")
        private Person(String name) {
            this.name = name;
        }
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        private String show(String nation) throws NullPointerException,CloneNotSupportedException {
            System.out.println("I am form" + nation);
            return nation;
        }
        private static void showInterests(){
            System.out.println("I like programmer");
        }
        @MyAnnotation(value = "b")
        public String show2(String publicMethod) {
            return publicMethod;
        }
        @Override
        public int compareTo(Object o) {
            return 0;
        }
        @Override
        public void info() {
            System.out.println("I am a Person");
        }
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", id=" + id +
                    '}';
        }
    }
    
    
    package reflection2;
    import org.junit.Test;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.ParameterizedType;
    import java.util.Arrays;
    /**
     * user:ypc;
     * date:2021-06-22;
     * time: 15:11;
     */
    public class ConstructorDemo {
        @Test
        public void test1() {
            Class clazz = Person.class;
            //       public    
            Constructor[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
            System.out.println();
            //                 
            Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
            for (Constructor declaredConstructor : declaredConstructors) {
                System.out.println(declaredConstructor);
            }
        }
        @Test
        public void test2() {
            //         
            Class clazz = Person.class;
            System.out.println(clazz.getSuperclass());
            //            
            System.out.println(clazz.getGenericSuperclass());
            //         
            System.out.println(((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0]);
            System.out.println();
            //         
            Class[] interfaces = clazz.getInterfaces();
            for (Class intF : interfaces) {
                System.out.println(intF);
            }
            System.out.println();
            //           
            Class[] supInterfaces = clazz.getSuperclass().getInterfaces();
            for (Class intF : supInterfaces) {
                System.out.println(intF);
            }
            //        
            System.out.println(clazz.getPackage());
            System.out.println();
            //         
            System.out.println(Arrays.toString(clazz.getAnnotations()));
            ;
        }
    }
    
    在这里插入图片描述
    실행 시 클래스 의 지정 속성,방법,구조 방법 을 반사 적 으로 호출 합 니 다.
    
    package reflection2;
    import org.junit.Test;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    /**
     * user:ypc;
     * date:2021-06-22;
     * time: 15:57;
     *             :  、  、    
     */
    public class ReflectionDemo {
        @Test
        public void test1() throws Exception {
            Class clazz = Person.class;
            //         
            Person person = (Person) clazz.newInstance();
            //       ,          public
            Field id = clazz.getField("id");
            id.set(person, 10001);
            int fieldId = (int) id.get(person);
            System.out.println(fieldId);
        }
        @Test
        public void test2() throws Exception {
            Class clazz = Person.class;
            //         
            Person person = (Person) clazz.newInstance();
            //getDeclaredField           
            Field name = clazz.getDeclaredField("name");
            //            
            name.setAccessible(true);
            //          
            name.set(person, "Tom");
            System.out.println(name.get(person));
        }
        //         
        @Test
        public void test3() throws Exception {
            Class clazz = Person.class;
            //         
            Person person = (Person) clazz.newInstance();
            //1.          getDeclaredMethod()                ,                  
            Method show = clazz.getDeclaredMethod("show", String.class);
            //2.            
            show.setAccessible(true);
            //3.  invoke()               ,                
            show.invoke(person, " CHN");
            //invoke                  
            Object returnValue = show.invoke(person, " CHN");
            System.out.println(returnValue);
            //       
            Method showInterests = clazz.getDeclaredMethod("showInterests");
            showInterests.setAccessible(true);
            showInterests.invoke(Person.class);
            //               ,  invoke      null
            System.out.println(showInterests.invoke(Person.class));
        }
    
        /*
                      
         */
        @Test
        public void test4() throws Exception {
            Class clazz = Person.class;
            //1.            
            Constructor constructor = clazz.getDeclaredConstructor(String.class);
            //2.             
            constructor.setAccessible(true);
            //3.                
            Person person = (Person) constructor.newInstance("Tom");
            System.out.println(person);
        }
    }
    
    test1():
    在这里插入图片描述
    test2():
    在这里插入图片描述
    test3():
    在这里插入图片描述
    test4():
    在这里插入图片描述
    총결산
    이 글 의 전반 부 는 여기까지 입 니 다.당신 에 게 도움 이 되 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 기 를 바 랍 니 다!

    좋은 웹페이지 즐겨찾기