>  기사  >  Java  >  Java 리플렉션 분석 소개

Java 리플렉션 분석 소개

高洛峰
高洛峰원래의
2017-03-09 19:05:40974검색

이 문서에서는 Java Reflection의 분석 및 소개를 설명합니다

1. Reflection이란?
Baidu Encyclopedia에서 우리는 모든 클래스에 대해 이 클래스의 모든 속성과 메서드를 알 수 있으며 해당 메서드와 속성을 호출할 수 있습니다. 속성을 변경할 수 있습니다. 그리고 이것이 Java가 동적(또는 준동적)으로 간주되는 이유입니다. 동적 언어의 일반적인 정의는 프로그램이 실행될 때 프로그램 구조나 변수 유형이 다음을 수행하도록 허용하기 때문입니다. 이 언어를 동적 언어라고 합니다. 이러한 관점에서 Perl, Python, Ruby는 동적 언어이고 C++, Java, C#은 동적 언어가 아닙니다.) 언어의 핵심 속성입니다.

2. 성찰은 무엇을 할 수 있나요?
우리는 리플렉션 메커니즘을 통해 프로그램이 런타임 시 수정자(수정자), 필드(속성), 메서드(메서드) 등을 포함하여 알려진 이름을 가진 모든 클래스의 내부 정보를 얻을 수 있다는 것을 알고 있습니다. 런타임 시 필드 내용 또는 호출 메서드가 변경됩니다. 그러면 코드를 보다 유연하게 작성할 수 있으며, 구성 요소 간 소스 코드 연결 없이 코드를 런타임에 조합할 수 있으며, 동적 프록시 구현 등도 줄일 수 있습니다. 반사를 부적절하게 사용하면 비용이 매우 많이 듭니다!

3. Reflection의 구체적인 구현

다음은 기본 클래스 Person

package com.ys.reflex;
public class Person {
    //私有属性
    private String name = "Tom";
    //公有属性
    public int age = 18;
    //构造方法
    public Person() {    
    }
    //私有方法
    private void say(){
        System.out.println("private say()...");
    }
    //公有方法
    public void work(){
        System.out.println("public work()...");
    }
}

Get the Class 3이다. 이 방법은

//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
//  类型的对象,而我不知道你具体是什么类,用这种方法
  Person p1 = new Person();
  Class c1 = p1.getClass();
        
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
//  这说明任何一个类都有一个隐含的静态成员变量 class
  Class c2 = Person.class;
        
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
//   但可能抛出 ClassNotFoundException 异常
  Class c3 = Class.forName("com.ys.reflex.Person");

다음 사항에 유의해야 합니다. 클래스는 JVM에서 하나의 Class 인스턴스만 갖습니다. 즉, 위에서 얻은 c1을 수행합니다. , c2, c3 같음을 비교하여 모두 참인지 확인

②, 멤버 변수, 멤버 메소드, 인터페이스, 슈퍼 클래스, 생성자 등을 다음을 통해 가져옵니다. Class 클래스

API를 보면 Class에 많은 메소드가 있음을 알 수 있습니다.

 getName(): 클래스의 전체 이름을 가져옵니다.
 getFields(): 클래스의 공개 유형 속성을 가져옵니다.
 getDeclaredFields(): 클래스의 모든 속성을 가져옵니다. 비공개 선언 및 상속 클래스 포함
 getMethods(): 클래스의 공개 유형 메서드를 가져옵니다.
 getDeclaredMethods(): 클래스의 모든 메소드를 가져옵니다. 비공개로 선언되고 상속된 클래스 포함
 getMethod(String name, Class[] 매개변수 유형): 클래스의 특정 메서드를 가져오고, name 매개 변수는 메서드 이름을 지정하고, 매개 변수 Types 매개 변수는 메서드의 매개 변수 유형을 지정합니다.
GetConstructors(): 클래스의 공개 유형 생성자를 가져옵니다.
 getConstructor(Class[] 매개변수 유형): 클래스의 특정 생성자 메서드를 가져옵니다. 매개변수 유형은 생성자 메서드의 매개변수 유형을 지정합니다.
 newInstance(): 매개변수 없이 클래스 생성자를 통해 이 클래스의 객체를 생성합니다.

위 방법을 종합적으로 설명하기 위해 예제를 사용합니다.

//获得类完整的名字
String className = c2.getName();
System.out.println(className);//输出com.ys.reflex.Person
        
//获得类的public类型的属性。
Field[] fields = c2.getFields();
for(Field field : fields){
   System.out.println(field.getName());//age
}
        
//获得类的所有属性。包括私有的和继承类的
Field [] allFields = c2.getDeclaredFields();
for(Field field : allFields){
    System.out.println(field.getName());//name    age
}
        
//获得类的public类型的方法。这里包括 Object 类的一些方法
Method [] methods = c2.getMethods();
for(Method method : methods){
    System.out.println(method.getName());//work waid equls toString hashCode等
}
        
//获得类的所有方法。
Method [] allMethods = c2.getDeclaredMethods();
for(Method method : allMethods){
    System.out.println(method.getName());//work say
}
        
//获得指定的属性
Field f1 = c2.getField("age");
System.out.println(f1);
//获得指定的私有属性
Field f2 = c2.getDeclaredField("name");
//启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
f2.setAccessible(true);
System.out.println(f2);
                
//创建这个类的一个对象
Object p2 =  c2.newInstance();
//将 p2 对象的  f2 属性赋值为 Bob,f2 属性即为 私有属性 name
f2.set(p2,"Bob");
//使用反射机制可以打破封装性,导致了java对象的属性不安全。 
System.out.println(f2.get(p2)); //Bob
        
//获取构造方法
Constructor [] constructors = c2.getConstructors();
for(Constructor constructor : constructors){
    System.out.println(constructor.toString());//public com.ys.reflex.Person()
}

4. 리플렉션 요약

리플렉션을 유연하게 사용하면 코드가 더욱 유연해집니다. 여기에 예제가 있습니다. JDBC 네이티브 코드 등록 드라이버, 최대 절전 모드의 엔터티 클래스, Spring의 AOP 등은 모두 리플렉션 구현을 가지고 있습니다. 그러나 모든 것에는 양면이 있습니다. 또한 합리적인 사용은 시스템의 성능과 복잡성을 증가시킵니다.

위 내용은 Java 리플렉션 분석 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.