10분 동안 자바의 반사를 이해해 드릴게요.
자바 반사는 우리가 실행할 때 클래스의 방법, 속성, 부류, 인터페이스 등 클래스의 내부 정보를 얻을 수 있는 메커니즘이다.즉, 반사는 본질적으로'반착'의 과정이다.우리가
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
류의 구조기 대상을 얻었다. 우리가 얻고 싶은 구조기의 형삼 유형은 People
과String
이기 때문에 우리는 int
과String.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();
}
총결산이상은 이 글의 전체 내용입니다. 여러분의 학습과 업무에 도움이 되기를 바랍니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
38. Java의 Leetcode 솔루션텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.