반사란 무엇이며 왜 유용한가?
반사란 무엇이며 왜 유용한가?
는 특히 히히 에 관심이 있다.Java
어떤 언어에서도 원칙은 같다고 생각합니다.
이름 리플렉션은 동일한 시스템(또는 시스템 자체)에서 다른 코드를 검사할 수 있는 코드를 설명하는 데 사용됩니다.
예를 들어 Java에 알 수 없는 유형의 객체가 있고, 존재하는 경우 해당 객체에 대해 'doSomething' 메서드를 호출하려고 합니다.Java의 정적 타이핑 시스템은 객체가 알려진 인터페이스를 준수하지 않는 한 실제로 이것을 지원하도록 설계되지 않았지만, 반사를 통해 당신의 코드는 객체를 보고 'doSomething'이라고 불리는 메서드가 있는지 확인하고 원한다면 호출할 수 있다.
Java에서 코드 예를 들자면 (문제의 오브젝트가 foo라고 상상해 주세요)
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
Java에서 가장 일반적인 사용 사례 중 하나는 주석과 함께 사용하는 것입니다.예를 들어 JUnit 4는 리플렉션을 사용하여 클래스에서 @Test 주석으로 태그된 메서드를 검색한 후 유닛테스트 실행 시 호출합니다.
http://docs.oracle.com/javase/tutorial/reflect/index.html에서 시작하는 데 도움이 되는 좋은 반영 사례가 몇 가지 있습니다.
마지막으로 C#과 같이 리플렉션을 지원하는 다른 정적 유형의 언어에서도 개념은 거의 유사합니다.동적으로 입력된 언어에서는 위에서 설명한 사용 사례는 덜 필요하지만(컴파일러는 어떤 오브젝트에서도 메서드를 호출할 수 있도록 허용하기 때문에 존재하지 않으면 런타임에 실패합니다), 두 번째 예는 여전히 일반적입니다.
코멘트에서 갱신:
시스템에서 코드를 검사하고 개체 유형을 확인하는 기능은 리플렉션이 아니라 Type Introspection입니다.리플렉션이란 자기성찰을 사용하여 런타임에 수정할 수 있는 기능입니다.일부 언어는 자기성찰을 지원하지만 반성을 지원하지 않으므로 여기서 구별이 필요합니다.예를 들어 C++가 있습니다.
리플렉션이란 런타임에 클래스, 메서드, 속성 등을 검사하고 동적으로 호출하는 언어의 기능입니다.
들어 라는 메서드가 있습니다.getClass()
시에 를 판별할 수 를 들어,를 「알 수 라고 ).Object
) - 이것은 사소한 것처럼 보일 수 있지만, 이러한 반영은 다음과 같은 덜 역동적인 언어에서는 불가능합니다.C++
. 컨스트럭터할 수 있습니다 고급 사용으로 메서드, 컨스트럭터 등을 나열하고 호출할 수 있습니다.
리플렉션은 컴파일 시에 모든 것을 "알" 필요가 없는 프로그램을 쓸 수 있게 해주기 때문에 중요합니다.이것들은 런타임에 함께 연결될 수 있기 때문에 더욱 역동적입니다.코드는 기존의 인터페이스에 대해 쓸 수 있지만 실제 사용되는 클래스는 컨피규레이션파일로부터의 리플렉션을 사용하여 인스턴스화할 수 있습니다.
많은 현대적 프레임워크는 바로 이러한 이유로 반성을 광범위하게 사용합니다.다른 대부분의 현대 언어들도 리플렉션(reflection)을 사용하고 있으며, 스크립트 언어(Python 등)에서는 이러한 언어의 일반적인 프로그래밍 모델 내에서 보다 자연스럽게 느껴지기 때문에 더욱 긴밀하게 통합됩니다.
제가 가장 좋아하는 반사 사용법 중 하나는 아래의 자바 덤프 방법입니다.임의의 오브젝트를 파라미터로 하여 Java reflection API를 사용하여 모든 필드 이름과 값을 출력합니다.
import java.lang.reflect.Array;
import java.lang.reflect.Field;
public static String dump(Object o, int callCount) {
callCount++;
StringBuffer tabs = new StringBuffer();
for (int k = 0; k < callCount; k++) {
tabs.append("\t");
}
StringBuffer buffer = new StringBuffer();
Class oClass = o.getClass();
if (oClass.isArray()) {
buffer.append("\n");
buffer.append(tabs.toString());
buffer.append("[");
for (int i = 0; i < Array.getLength(o); i++) {
if (i < 0)
buffer.append(",");
Object value = Array.get(o, i);
if (value.getClass().isPrimitive() ||
value.getClass() == java.lang.Long.class ||
value.getClass() == java.lang.String.class ||
value.getClass() == java.lang.Integer.class ||
value.getClass() == java.lang.Boolean.class
) {
buffer.append(value);
} else {
buffer.append(dump(value, callCount));
}
}
buffer.append(tabs.toString());
buffer.append("]\n");
} else {
buffer.append("\n");
buffer.append(tabs.toString());
buffer.append("{\n");
while (oClass != null) {
Field[] fields = oClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
buffer.append(tabs.toString());
fields[i].setAccessible(true);
buffer.append(fields[i].getName());
buffer.append("=");
try {
Object value = fields[i].get(o);
if (value != null) {
if (value.getClass().isPrimitive() ||
value.getClass() == java.lang.Long.class ||
value.getClass() == java.lang.String.class ||
value.getClass() == java.lang.Integer.class ||
value.getClass() == java.lang.Boolean.class
) {
buffer.append(value);
} else {
buffer.append(dump(value, callCount));
}
}
} catch (IllegalAccessException e) {
buffer.append(e.getMessage());
}
buffer.append("\n");
}
oClass = oClass.getSuperclass();
}
buffer.append(tabs.toString());
buffer.append("}\n");
}
return buffer.toString();
}
반영의 용도
리플렉션은 Java 가상 시스템에서 실행 중인 애플리케이션의 런타임 동작을 검사하거나 수정하는 기능이 필요한 프로그램에서 일반적으로 사용됩니다.이것은 비교적 고도의 기능으로 언어의 기초를 잘 이해하고 있는 개발자만이 사용할 수 있습니다.이러한 점을 염두에 두고 리플렉션은 강력한 기술이며, 그렇지 않으면 불가능했던 작업을 애플리케이션이 수행할 수 있도록 지원합니다.
확장성 기능
응용 프로그램은 완전 수식 이름을 사용하여 확장성 개체의 인스턴스를 생성하여 외부 사용자 정의 클래스를 사용할 수 있습니다.Class Browser and Visual Development Environment 클래스 브라우저는 클래스의 멤버를 열거할 수 있어야 합니다.시각적 개발 환경에서는 유형 정보를 반영하여 사용할 수 있으므로 개발자가 올바른 코드를 작성할 수 있습니다.디버거와 테스트 툴 디버거는 클래스 내에서 개인 구성원을 검사할 수 있어야 합니다.테스트 하니스는 반사를 사용하여 클래스에 정의된 검색 가능한 집합 API를 체계적으로 호출하여 테스트 스위트에서 높은 수준의 코드 적용 범위를 보장할 수 있습니다.
반사의 결점
반성은 강력하지만 무분별하게 사용해서는 안 된다.반사를 사용하지 않고 조작할 수 있는 경우에는 사용을 피하는 것이 바람직하다.반사를 통해 코드에 액세스할 때는 다음 사항에 유의해야 합니다.
- 퍼포먼스 오버헤드
리플렉션에는 동적으로 확인되는 유형이 포함되므로 특정 Java 가상 시스템 최적화를 수행할 수 없습니다.따라서 반사 연산은 비반사 연산에 비해 성능이 느리므로 성능에 민감한 애플리케이션에서 자주 호출되는 코드 섹션에서는 피해야 합니다.
- 보안상의 제약 사항
리플렉션에는 실행 시 권한이 필요하며, 이는 보안 관리자에서 실행할 때 존재하지 않을 수 있습니다.이는 애플릿과 같은 제한된 보안 컨텍스트에서 실행해야 하는 코드에 대한 중요한 고려 사항입니다.
- 내부 폭로
리플렉션은 코드가 개인 필드 및 메서드에 액세스하는 등 비반사 코드에서 불법인 작업을 수행할 수 있도록 하기 때문에 리플렉션을 사용하면 예기치 않은 부작용이 발생할 수 있으며 이로 인해 코드가 기능하지 않게 되어 이식성이 파괴될 수 있습니다.반사 코드는 추상화를 깨기 때문에 플랫폼 업그레이드에 따라 동작이 변경될 수 있습니다.
소스: Reflection API
리플렉션이란 애플리케이션이나 프레임워크가 아직 작성되지 않았을 수 있는 코드로 동작할 수 있도록 하기 위한 중요한 메커니즘입니다.
일반적인 web.xml 파일을 예로 들어 보겠습니다.여기에는 중첩된 서블릿 클래스 요소가 포함된 서블릿 요소 목록이 포함됩니다.서블릿 컨테이너는 web.xml 파일을 처리하고 리플렉션을 통해 각 서블릿클래스의 새 인스턴스를 만듭니다.
다른 예로는 Java API for XML Parsing(JAXP)이 있습니다.XML 파서 공급자는 리플렉션을 통해 새 인스턴스를 구축하는 데 사용되는 잘 알려진 시스템 속성을 통해 '플러그인'됩니다.
마지막으로, 가장 포괄적인 예는 반사를 이용하여 콩을 만들고 프록시 사용을 많이 하는 스프링입니다.
모든 언어가 반성을 지원하는 것은 아니지만, 반성을 지원하는 언어에서 원칙은 일반적으로 동일합니다.
리플렉션이란, 프로그램의 구조를 「반성」하는 기능입니다.아니면 더 구체적이거나.보유하고 있는 오브젝트 및 클래스를 확인하고 구현된 메서드, 필드 및 인터페이스에 대한 정보를 프로그래밍 방식으로 가져옵니다.주석과 같은 것도 볼 수 있습니다.
그것은 많은 상황에서 유용합니다.코드에 동적으로 클래스를 삽입할 수 있는 모든 장소.많은 객체 관계형 매퍼는 리플렉션을 사용하여 어떤 객체를 사용할지 미리 알지 못한 채 데이터베이스에서 객체를 인스턴스화할 수 있습니다.플러그인 아키텍처는 반사가 유용한 또 다른 장소입니다.이러한 상황에서는 코드를 동적으로 로드하여 플러그인으로 사용하는 올바른 인터페이스를 구현하는 유형이 있는지 확인하는 것이 중요합니다.
리플렉션을 사용하면 새로운 오브젝트의 인스턴스화, 메서드의 호출 및 클래스 변수에 대한 get/set 조작을 실행 시 해당 구현에 대한 사전 지식 없이 동적으로 수행할 수 있습니다.
Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();
//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class);
Object returnValue = method.invoke(null, "parameter-value1");
위의 예에서 null 파라미터는 메서드를 호출하는 오브젝트입니다.메서드가 정적인 경우 null을 제공합니다.메서드가 스태틱하지 않은 경우 호출 중에 null 대신 유효한 MyObject 인스턴스를 제공해야 합니다.
Reflection을 사용하면 클래스의 개인 멤버/메서드에 액세스할 수도 있습니다.
public class A{
private String str= null;
public A(String str) {
this.str= str;
}
}
.
A obj= new A("Some value");
Field privateStringField = A.class.getDeclaredField("privateString");
//Turn off access check for this field
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
- 패키지반사 패키지)를
java.lang.reflect
에는, 「클래스 메타데이터」를 할 수 있습니다java.lang.Class
.
리플렉션은 매우 강력한 API이지만 런타임에 모든 유형을 해결하므로 과도하게 사용하면 응용 프로그램이 느려질 수 있습니다.
Java Reflection은 매우 강력하며 매우 유용합니다.Java Reflection은 클래스, 인터페이스, 필드 및 메서드를 컴파일할 때 클래스, 메서드 등의 이름을 몰라도 런타임에 검사할 수 있도록 합니다.리플렉션을 사용하여 새 객체를 인스턴스화하고 메서드를 호출하며 필드 값을 가져오거나 설정할 수도 있습니다.
Java Reflection의 간단한 예에서는 리플렉션을 사용하는 방법을 보여 줍니다.
Method[] methods = MyObject.class.getMethods();
for(Method method : methods){
System.out.println("method = " + method.getName());
}
이 예에서는 MyObject라는 클래스에서 Class 객체를 가져옵니다.이 예에서는 class 객체를 사용하여 해당 클래스의 메서드 목록을 가져오고 메서드를 반복하여 이름을 인쇄합니다.
이 모든 것이 어떻게 작동하는지 정확히 여기에 설명되어 있습니다.
편집: 거의 1년이 지난 후 이 답변을 편집하고 있습니다.반사에 대한 글을 읽으면서 Reflection을 몇 가지 더 사용할 수 있게 되었습니다.
- 봄에는 다음과 같은 콩 구성이 사용됩니다.
<bean id="someID" class="com.example.Foo">
<property name="someField" value="someValue" />
</bean>
스프링 컨텍스트는 이 <bean> 요소를 처리할 때 Class.forName(String)을 인수 "com.example"과 함께 사용합니다.Foo"를 클릭하여 해당 클래스를 인스턴스화합니다.
그런 다음 리플렉션을 사용하여 <property > 요소의 적절한 세터를 가져와 지정된 값으로 설정합니다.
- Junit은 특히 개인/보호 메서드를 테스트하기 위해 Reflection을 사용합니다.
Private 메서드의 경우
Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
개인 필드의 경우
Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
예:
API 메서드를 사용하여 취득한 오브젝트를 어플리케이션에 제공하는 리모트애플리케이션을 예로 들어 보겠습니다.이 오브젝트에 따라서는 어떤 종류의 계산을 실행할 필요가 있을 수 있습니다.
프로바이더는 오브젝트가 3가지 타입이 될 수 있음을 보증하며, 우리는 오브젝트 타입에 따라 계산을 수행해야 합니다.
따라서 각각 다른 논리를 포함하는 3개의 클래스로 구현할 수 있습니다.분명히 오브젝트 정보는 런타임에 사용할 수 있으므로 계산을 수행하기 위해 정적으로 코드화할 수 없습니다.따라서 리플렉션에서는 프로바이더로부터 수신한 오브젝트를 기반으로 계산을 실행하는 데 필요한 클래스의 오브젝트를 인스턴스화하기 위해 사용됩니다.
간단한 반성의 예시입니다.체스 게임에서는 런타임에 사용자가 무엇을 이동할지 알 수 없습니다.리플렉션은 런타임에 이미 구현되어 있는 호출 메서드에 사용할 수 있습니다.
public class Test {
public void firstMoveChoice(){
System.out.println("First Move");
}
public void secondMOveChoice(){
System.out.println("Second Move");
}
public void thirdMoveChoice(){
System.out.println("Third Move");
}
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Test test = new Test();
Method[] method = test.getClass().getMethods();
//firstMoveChoice
method[0].invoke(test, null);
//secondMoveChoice
method[1].invoke(test, null);
//thirdMoveChoice
method[2].invoke(test, null);
}
}
리플렉션은 실행 시 메서드, 클래스, 인터페이스의 동작을 검사하거나 수정하는 데 사용되는 API입니다.
- 는 성찰하다 아래에 .
java.lang.reflect package
. - 반사는 개체가 속한 클래스에 대한 정보와 개체를 사용하여 실행할 수 있는 클래스의 메서드를 제공합니다.
- 리플렉션을 통해 메서드와 함께 사용되는 액세스 지정자에 관계없이 런타임에 메서드를 호출할 수 있습니다.
java.lang
★★★★★★★★★★★★★★★★★」java.lang.reflect
패키지는 Java 리플렉션을 위한 클래스를 제공합니다.
반사를 통해 다음 정보를 얻을 수 있습니다.
클래스 The
getClass()
method는 개체가 속한 클래스의 이름을 가져오는 데 사용됩니다.컨스트럭터
getConstructors()
method는 객체가 속한 클래스의 퍼블릭컨스트럭터를 취득하기 위해 사용됩니다.방법
getMethods()
method는 개체가 속한 클래스의 퍼블릭 메서드를 가져오는 데 사용됩니다.
Reflection API는 주로 다음에서 사용됩니다.
IDE(이클립스, MyEclipse, NetBeans)
디버거 및 테스트 도구 등
Reflection을 사용하는 장점:
확장성 기능:응용 프로그램은 완전 수식 이름을 사용하여 확장성 개체의 인스턴스를 생성하여 외부 사용자 정의 클래스를 사용할 수 있습니다.
디버깅 및 테스트 도구: 디버거는 반사의 속성을 사용하여 클래스의 개인 구성원을 검사합니다.
결점:
퍼포먼스 오버헤드:반사 동작은 비반사 동작보다 퍼포먼스가 느립니다.퍼포먼스에 민감한 어플리케이션에서 자주 호출되는 코드 섹션에서는 피해야 합니다.
내부 노출: 반사 코드는 추상화를 깨기 때문에 플랫폼 업그레이드에 따라 동작이 변경될 수 있습니다.
참조: Java Reflection javarvisit되었습니다.블로그 스팟을 참조하십시오.에
내가 아는 바로는:
리플렉션을 통해 프로그래머는 프로그램 내의 엔티티에 동적으로 접근할 수 있습니다. 즉, 프로그래머가 클래스 또는 그 메서드에 대해 알지 못하는 경우 애플리케이션을 코딩하는 동안, 그는 리플렉션을 사용하여 동적으로 (실행 시) 그러한 클래스를 사용할 수 있습니다.
클래스 이름이 자주 변경되는 시나리오에서 자주 사용됩니다.그러한 상황이 발생하면, 프로그래머가 애플리케이션을 다시 쓰고 클래스의 이름을 계속해서 변경하는 것은 복잡합니다.
대신 반사를 사용함으로써 클래스 이름이 변경될 수 있다는 우려가 있습니다.
리플렉션은 프로그램의 런타임 정보에 액세스하고 동작을 수정할 수 있는 함수 집합입니다(몇 가지 제한 사항이 있음).
프로그램의 메타 정보에 따라 실행 시 동작을 변경할 수 있으므로, 즉 함수의 반환 유형을 확인하고 상황에 대한 처리 방법을 변경할 수 있으므로 유용합니다.
예를 들어 C#에서는 런타임에 어셈블리(.dll)를 로드하여 클래스 사이를 이동하고 발견된 내용에 따라 액션을 수행할 수 있습니다.또한 런타임에 클래스의 인스턴스를 만들거나 해당 메서드를 호출할 수도 있습니다.
어디에 유용할까요?매번 유용하지는 않지만 구체적인 상황에서 유용합니다.예를 들어 로그 목적으로 클래스 이름을 가져오거나 구성 파일에 지정된 내용에 따라 이벤트에 대한 핸들러를 동적으로 만드는 등의 작업을 수행할 수 있습니다.
나는 단지 나열된 모든 것에 몇 가지 포인트를 더하고 싶다.
Reflection API로 범용을 쓸 수 있습니다.toString()
메서드를 지정합니다.
디버깅에 도움이 됩니다.
다음은 예를 제시하겠습니다.
class ObjectAnalyzer {
private ArrayList<Object> visited = new ArrayList<Object>();
/**
* Converts an object to a string representation that lists all fields.
* @param obj an object
* @return a string with the object's class name and all field names and
* values
*/
public String toString(Object obj) {
if (obj == null) return "null";
if (visited.contains(obj)) return "...";
visited.add(obj);
Class cl = obj.getClass();
if (cl == String.class) return (String) obj;
if (cl.isArray()) {
String r = cl.getComponentType() + "[]{";
for (int i = 0; i < Array.getLength(obj); i++) {
if (i > 0) r += ",";
Object val = Array.get(obj, i);
if (cl.getComponentType().isPrimitive()) r += val;
else r += toString(val);
}
return r + "}";
}
String r = cl.getName();
// inspect the fields of this class and all superclasses
do {
r += "[";
Field[] fields = cl.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
// get the names and values of all fields
for (Field f : fields) {
if (!Modifier.isStatic(f.getModifiers())) {
if (!r.endsWith("[")) r += ",";
r += f.getName() + "=";
try {
Class t = f.getType();
Object val = f.get(obj);
if (t.isPrimitive()) r += val;
else r += toString(val);
} catch (Exception e) {
e.printStackTrace();
}
}
}
r += "]";
cl = cl.getSuperclass();
} while (cl != null);
return r;
}
}
성찰은 사물이 그들의 모습을 보게 하는 것이다.이 주장은 반성과는 무관해 보인다.사실, 이것은 "자기 식별" 능력입니다.
리플렉션 자체는 Java 및 C#과 같이 자기 인식 및 자기 감지 기능이 결여된 언어를 가리키는 단어입니다.그들은 자기 인식 능력이 없기 때문에 우리가 그것이 어떻게 보이는지 관찰하고 싶을 때, 우리는 그것이 어떻게 보이는지 성찰할 수 있는 또 다른 것이 있어야 한다.Ruby나 Python과 같은 뛰어난 동적 언어는 다른 개인의 도움 없이도 자신의 반사를 인지할 수 있습니다.Java의 오브젝트는 반사 클래스의 오브젝트인 거울이 없으면 어떻게 보이는지 인식할 수 없지만 Python의 오브젝트는 거울이 없어도 인식할 수 있습니다.그래서 자바에서 반영이 필요한 겁니다.
Java 문서 페이지에서
java.lang.reflect
객체에 반영 및 합니다.Reflection을 사용하면 로드된 클래스의 필드, 메서드 및 생성자에 대한 정보에 프로그래밍 방식으로 액세스하고 기본 필드, 메서드 및 생성자를 사용하여 보안 제한 내에서 작동합니다.
AccessibleObject
한 경우 할 수 있습니다.ReflectPermission
사용할 수 있습니다.
패키지의 및 " " " "java.lang.Class
과 "Debuger", "Debuger", "Debuger", "Debuger", "Dubject Inspector", " Browser "Debuger", "Debugger", "D" 등의 합니다.Object Serialization
★★★★★★★★★★★★★★★★★」JavaBeans
오브젝트의 ) 에 대한
다음과 같은 기능이 포함되어 있습니다.
- 클래스 개체를 가져오는 중,
- 클래스 속성 검사(필드, 메서드, 생성자),
- 필드 값 설정 및 가져오기
- 호출 메서드,
- 개체의 새 인스턴스를 만드는 중입니다.
클래스별로 공개되는 메서드에 대해서는 이 매뉴얼링크를 참조해 주십시오.
이 기사(Dennis Sosnoski, Sosnoski Software Solutions, Inc. 사장) 및 이 기사(보안 탐색 PDF):
Reflection을 사용하는 것보다 상당한 단점이 있음을 알 수 있습니다.
Reflection 사용자:
- 프로그램 컴포넌트를 동적으로 링크하는 매우 다양한 방법을 제공합니다.
- 이것은 매우 일반적인 방법으로 오브젝트로 동작하는 라이브러리를 작성하는 데 유용합니다.
반성의 결점:
- 필드 및 메서드 액세스에 사용할 경우 리플렉션이 직접 코드보다 훨씬 느립니다.
- 코드 안에서 실제로 무슨 일이 일어나고 있는지 알 수 없습니다.
- 소스 코드를 바이패스하면 유지 보수 문제가 발생할 수 있습니다.
- 리플렉션 코드도 해당 다이렉트 코드보다 복잡합니다.
- 데이터 액세스 보호 및 유형 안전과 같은 주요 Java 보안 제약 조건을 위반할 수 있습니다.
일반적인 남용:
- 제한된 클래스 로드,
- 제한된 클래스의 컨스트럭터, 메서드 또는 필드에 대한 참조를 얻습니다.
- 새 개체 인스턴스 만들기, 메서드 호출, 제한된 클래스의 필드 값 가져오기 또는 설정.
반사 기능의 남용에 관한 SE 질문을 참조하십시오.
Java에서 개인 필드를 읽으려면 어떻게 해야 합니까?
요약:.
시스템 코드 내에서 실행되는 기능을 안전하지 않게 사용하면 Java 보안 모델이 쉽게 손상될 수 있습니다.따라서 이 기능을 적게 사용합니다.
이름 자체에서 알 수 있듯이 실행 시 동적으로 인스턴스를 생성하는 메서드를 호출하는 기능을 제공하는 것 외에 클래스 메서드 등의 기능을 보유하고 있는 것을 반영합니다.
실제로 코드를 알지 못한 채 서비스를 호출하기 위해 많은 프레임워크와 나무 아래에 있는 애플리케이션에서 사용됩니다.
반사를 통해 보다 일반적인 코드를 작성할 수 있습니다.실행 시 개체를 만들고 실행 시 메서드를 호출할 수 있습니다.따라서 프로그램을 고도로 파라미터화할 수 있습니다.또한 객체와 클래스를 자세히 조사하여 외부에 노출된 변수와 메서드를 탐지할 수 있습니다.
Reflection
용도가 다양합니다.제가 더 친숙한 것은 바로 코드를 만들 수 있다는 것입니다.
IE: 동적 클래스, 함수, 컨스트럭터 - 모든 데이터 기반(xml/array/sql 결과/하드코드 등)
나는 이 질문에 본보기로 답하고 싶다.일단은Hibernate
프로젝트 용도Reflection API
발생시키다CRUD
실행 중인 어플리케이션과 지속성 스토어 사이의 틈을 메우기 위한 스테이트먼트.내의 , 「이러다」는Hibernate
에서는, 데이터 스토어에 데이터를 보관 유지하기 위해서, 또는 그 반대의 경우도 알고 있을 필요가 있습니다.
으로 동작합니다.Lombok Project
컴파일 시 코드를 삽입하기만 하면 도메인 클래스에 코드가 삽입됩니다.(게터나 세터도 괜찮다고 생각합니다)
Hibernate
골랐어요.reflection
애플리케이션 빌드 프로세스에 미치는 영향이 최소화되기 때문입니다.
부터는 Java 7이 있습니다.MethodHandles
해서 '이렇게 하다'라고 하는 거죠Reflection API
를 복사하여 만 하면 됩니다프로젝트에서는 로거를 사용하기 위해 다음 코드를 복사하여 붙여넣기만 하면 됩니다.
Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());
이 경우 오타가 나기 어렵기 때문입니다.
예를 들어 설명하는 것이 최선이고, 어떤 대답도 그렇게 하지 않는 것 같기 때문에...
리플렉션을 사용하는 실용적인 예로는 Java로 작성된 Java Language Server나 PHP로 작성된 PHP Language Server 등이 있습니다.언어 서버는 자동 완성, 정의로 이동, 컨텍스트 도움말, 힌트 유형 등의 IDE 기능을 제공합니다.입력 시 모든 태그 이름(자동 완성 가능한 단어)이 가능한 모든 일치 항목을 표시하도록 하려면 언어 서버가 문서 블록 및 개인 구성원을 포함한 클래스에 대한 모든 내용을 검사해야 합니다.그러기 위해서는 해당 클래스의 반영이 필요하다.
다른 예로는 개인 방법의 단위 테스트를 들 수 있습니다.이를 위한 한 가지 방법은 테스트 설정 단계에서 반사를 생성하고 방법의 범위를 공개로 변경하는 것입니다.물론 개인적인 방법이 직접적으로 시험되어서는 안 된다고 주장할 수 있지만 그것이 요점은 아니다.
reflection을 사용하여 클래스 이름(String의 클래스 이름)을 기반으로 개체를 만들고 해당 클래스의 메서드를 호출합니다.
Object obj = Class.forName(config.getClassPath())
.getDeclaredConstructor()
.newInstance();
Method method = obj.getClass().getMethod("getCustomer", SearchObject.class, ObjectConfig.class,
HttpServletRequest.class);
method.invoke(obj, searchObject, config, request);
단, 중요한 문제 중 하나는 해당 클래스에서 자동 전원을 켜면 null로 재초기화된다는 것입니다.
중요한
Java 9부터는 package-info.java가 모듈을 열고 리플렉션액세스를 하지 않는 한 리플렉션 기능을 사용할 수 없게 됩니다.
기본적으로는 모듈 내의 모든 패키지에 대한 "reflection" 액세스는 거부됩니다.
언급URL : https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful
'programing' 카테고리의 다른 글
VueJ 컴포넌트에서 데이터를 가져오는 방법s (0) | 2022.08.25 |
---|---|
django-rest에서 데이터를 검색하여 형식으로 표시 (0) | 2022.08.25 |
fread는 실제로 어떻게 작동합니까? (0) | 2022.08.25 |
PHP의 join()과 같은 어레이의 Java 함수? (0) | 2022.08.25 |
vue-tables-2의 데이터 새로고침(Vuex) (0) | 2022.08.25 |