10분 동안 자바의 반사를 이해해 드릴게요.

8221 단어 java반사
1. 소개
자바 반사는 우리가 실행할 때 클래스의 방법, 속성, 부류, 인터페이스 등 클래스의 내부 정보를 얻을 수 있는 메커니즘이다.즉, 반사는 본질적으로'반착'의 과정이다.우리가 new를 통해 클래스의 실례를 만들 때 실제로는 자바 가상 기기가 이 클래스Class의 대상이 운행할 때 구축된 것이고 반사는 하나의 클래스Class의 대상을 통해 그 정의 정보를 얻는다. 따라서 우리는 그 클래스의 속성, 방법, 이 클래스의 부류, 어떤 인터페이스를 실현했는지 알 수 있다.
클래스
우리는javac를 사용하면java 파일.class 파일, 이거.class 파일은 클래스에 대한 우리의 원시적인 정의 정보(부류, 인터페이스, 구조기, 속성, 방법 등)를 포함하고 있습니다.class 파일은 실행할 때 JVM(Java Virtual Machine)에 로드됩니다.class 파일이 불러오면 JVM은 클래스 대상을 생성합니다. 프로그램에서 new를 통해 실례화된 대상은 실제로 실행할 때 해당하는 클래스 대상에 따라 구성됩니다.정확히 말하면 이 Class 대상은 실제적으로 ClassLoader 범용 클래스의 실례이다. 예를 들어 java.lang.Class<T> 대상은 Class<MyClass> 클래스의 정의 정보를 봉인한MyClass 실례이다.Class<T>류는 공유 구조기가 존재하지 않기 때문에 이 류를 직접 실례화할 수 없습니다. 우리는 다음과 같은 방법을 통해 클래스 대상을 얻을 수 있습니다.
다음 설명에서는 People 클래스와 Student 클래스를 예로 들어 보겠습니다.

public class People {
  private String name;
  private int age;
  public People(String name, int age) {
   this.name = name;
    this.age = age;
  }
  public int getAge() {
   return age;
  } 
  public String getName() {
   return name;
  } 
  public void setAge(int age) {
   this.age = age;
  } 
  public void setName(String name) {
   this.name = name;
  }
  public void speak() {
  System.out.println(getName() + " " + getAge());
  }
}

public class Student extends People {
 private int grade;
 public Student(String name, int age) { 
 super(name, age); 
 }
 public Student(String name, int age, int grade) {
 super(name, age);   
 this.grade = grade; 
 }  
 public int getGrade() { 
 return grade; 
 }  
 public void setGrade(int grade) { 
 this.grade = grade; 
 } 
 private void learn(String course) { 
 System.out.println(name + " learn " + course); 
 }
}
클래스 이름으로 Class 객체 가져오기
컴파일러에서 클래스의 이름을 알면 클래스 대상을 얻을 수 있습니다.

Class<People> peopleClass = People.class;
클래스의 전체 경로 이름에 따라 클래스 객체를 가져오는 방법은 다음과 같습니다.

// People com.test 
Class<People> peopleClass = Class.forName("com.test.People");
java.lang.Class<T> 방법의 매개 변수는 클래스의 전체 경로 이름이어야 합니다.실제로, 우리가'importcom.test.People'만 있다면,'Class.forName()'을 통해 그의 클래스 대상을 얻을 수 있으며, 전체 경로를 쓰지 않아도 된다.People.class 방법을 호출할 때 Class.forName() 대응하는 클래스를 찾지 못하면 classpath 던진다.)
객체 자체를 통해 클래스 객체 가져오기

People people = new People("Bill", 18);
Class<People> peopleClass = people.getClass();
반사를 통해 클래스를 얻는 구조기
일단 우리가 ClassNotFoundException 클래스의 대상을 얻게 되면, 우리는 이 클래스 대상을 통해 People 클래스의 원시적인 정의 정보를 얻을 수 있다.우선, 우리는 People류의 구조기 대상을 얻는다. 이 구조기 대상이 있으면 우리는 People대상을 만들 수 있다.예를 들어, 우리는 Student에 있을 수 있다.java에 다음 코드를 추가합니다.

public static void main(String[] args) { 
 Class<People> pClass = People.class; 
 try { 
 Constructor<People> constructor = pClass.getConstructor(String.class, int.class);  
 People people = constructor.newInstance("Bill", 18);     
 obj.speak(); 
 } catch (Exception e) { 
 } 
}
위에서 우리는 People 방법을 호출하여 getConstructor류의 구조기 대상을 얻었다. 우리가 얻고 싶은 구조기의 형삼 유형은 PeopleString이기 때문에 우리는 intString.class를 전입했다.구조기 대상이 있으면 int.class 방법으로 newInstance 대상을 만들 수 있습니다.
반사를 통해 클래스의 people, Constructor, Method 대상을 얻은 후, 이러한 대상의 방법을 호출하기 전에 이 대상의 Field 표지판을 accessible 로 설정하여 자바 언어 접근 검사를 취소하면 반사 속도를 높일 수 있습니다.다음 코드와 같습니다.

Constructor<People> constructor = peopleClass.getConstructor(String.class, 
 int.class);
//   constructor   Accessible ture Java 
constructor.setAccessible(true);
반사를 통해 클래스의 설명을 얻는 방법
현재 클래스에서 선언된 방법을 가져옵니다. (부류에서 계승된 것은 포함하지 않음)
현재 클래스에서 성명된 모든 방법을 얻으려면 클래스의 true 함수를 통해 현재 클래스에서 성명된 모든 방법getDeclaredMethods , private, public 등 여러 가지 방법을 얻을 수 있습니다. 이 함수는 static 대상 그룹을 되돌려줍니다. 그 중의 각 Method 대상은 하나의 클래스에서 성명된 방법을 나타냅니다.지정한 방법을 얻으려면 Method 를 호출할 수 있습니다.
다음 코드와 같습니다.

private static void showDeclaredMethods() { 
 Student student = new Student("Bill", 18); 
 // Student  
 Method[] methods = student.getClass().getDeclaredMethods();  
 try {  
  // learnMethod ( learn ) 
  Method learnMethod = student.getClass().getDeclaredMethod("learn", 
   String.class);    
  // learn  
  Class<?>[] paramClasses = learnMethod.getParameterTypes() ;  
  for (Class<?> class : paramClasses) {  
  System.out.println("learn : " + class.getName()); 
  }    
  // learn private 
  System.out.println(learnMethod.getName() + " is private " 
   + Modifier.isPrivate(learnMethod.getModifiers())); 
  // learn  
  learnMethod.invoke(student, "Java Reflection"); 
 } catch (Exception e) { 
 }
}
현재 클래스와 상위 클래스에서 설명한 공유 방법 가져오기
현재 클래스와 상위 클래스에 설명된 모든 getDeclaredMethod(String name, Class...<T> parameterTypes) 방법을 가져오려면 public 함수를 호출할 수 있고, 지정한 getMethods 방법을 가져오려면 public 방법을 호출할 수 있습니다.다음 코드를 참조하십시오.

private static void showMethods() { 
 Student student = new Student("mr.simple"); 
 //  public ( Student ) 
 Method[] methods = student.getClass().getMethods(); 
 try { 
 // ,  getMethod public , private  
 Method learnMethod = student.getClass().getMethod("learn", String.class);
 } catch (Exception e) { 
 }
}
클래스에 정의된 속성을 반사하여 가져오기
획득 속성은 획득 방법과 유사하지만 대getMethod/getMethods() 방법의 호출을 대getDeclaredMethods()/getFields() 방법의 호출로 바꿨을 뿐입니다.
현재 클래스에 정의된 속성 가져오기 (부류에서 상속된 속성 포함하지 않음)
현재 클래스에 정의된 모든 속성getDeclaredFields(), private, public 등 각종 속성을 가져오려면 Class 대상의 static 함수를 호출할 수 있습니다.지정한 속성을 얻으려면 getDeclaredFields 을 호출할 수 있습니다.
다음 코드와 같습니다.

private static void showDeclaredFields() { 
 Student student = new Student("Bill", 18); 
 //   
 Field[] fields = student.getClass().getDeclaredFields(); 
 try { 
 //   
 Field gradeField = student.getClass().getDeclaredField("grade"); 
 //   
 System.out.println("The grade is : " + gradeField.getInt(student)); 
 //   
 gradeField.set(student, 10); 
 } catch (Exception e) { 
 } 
}
현재 클래스와 부모 클래스에 정의된public 속성 가져오기
현재 클래스와 상위 클래스에 정의된 모든 getDeclaredField 속성을 가져오려면 public 대상의 Class 함수를 호출하고, 지정한 getFields 속성을 가져오려면 public 방법을 호출할 수 있습니다. 다음 코드와 같습니다.

private static void showFields() { 
 Student student = new Student("Bill", 18);   
 //  public  
 Field[] publicFields = student.getClass().getFields();  
}
반사를 통해 클래스의 부류와 클래스가 실현하는 인터페이스 얻기
상위 클래스 가져오기getField 객체의 Class 메서드를 호출하면 다음 코드와 같습니다.

Student student = new Student("Bill", 18);
Class<?> superClass = student.getClass().getSuperclass();
구현된 인터페이스 가져오기
클래스가 어떤 인터페이스를 구현했는지 알고 싶으면 getSuperClass 대상의 Class 방법을 호출해야 한다. 아래 코드와 같다.

private static void showInterfaces() { 
 Student student = new Student("Bill", 19); 
 Class<?>[] interfaces = student.getClass().getInterfaces();
}
총결산
이상은 이 글의 전체 내용입니다. 여러분의 학습과 업무에 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기