1. 개념
Reflection은 Java의 다양한 구성 요소를 해당 Java 클래스에 매핑하는 것입니다.
Class 클래스의 구성 방법은 비공개이며 JVM에 의해 생성됩니다.
리플렉션은 프로그램이 런타임 중에 자체 검사를 수행하고 내부 멤버를 작동할 수 있도록 하는 Java 언어의 기능입니다(컴파일되지 않음에 유의하세요). 예를 들어, Java 클래스가 모든 멤버 변수와 메소드를 가져와 표시할 수 있습니다. Java의 이러한 기능은 실제 응용 프로그램에서는 많이 사용되지 않을 수 있지만, 이 기능은 다른 프로그래밍 언어에는 전혀 존재하지 않습니다. 예를 들어 Pascal, C 또는 C++에서는 프로그램의 함수 정의에 대한 정보를 얻을 수 있는 방법이 없습니다. (Sun에서)
JavaBean은 일부 도구가 소프트웨어 구성 요소를 시각적으로 작동할 수 있도록 하는 실용적인 리플렉션 애플리케이션 중 하나입니다. 이러한 도구는 리플렉션을 통해 Java 구성 요소(클래스)의 속성을 동적으로 로드하고 가져옵니다.
리플렉션은 1.2부터 사용되었습니다. 이후의 세 가지 주요 프레임워크는 모두 "Class" 클래스의 경우 메모리의 바이트코드를 직접 사용할 수 없습니다.
클래스 클래스 인스턴스는 실행 중인 Java 애플리케이션의 클래스와 인터페이스를 나타냅니다. 열거형은 클래스이고 주석은 인터페이스입니다. 각 배열은 요소 유형과 차원이 동일한 모든 배열에서 공유되는 Class 개체에 매핑되는 클래스에 속합니다. 기본 Java 유형(boolean, byte, char, short, int, long, float 및 double)과 키워드 void도 Class 객체로 표시됩니다. 클래스에는 공개 생성자가 없습니다. 클래스 객체는 클래스가 로드될 때 그리고 클래스 로더에서 정의 클래스 메소드를 호출하여 JVM(Java Virtual Machine)에 의해 자동으로 생성됩니다.1 Person p1 = new Person(); 2 //下面的这三种方式都可以得到字节码 3 CLass c1 = Date.class(); 4 p1.getClass(); 5 //若存在则加载,否则新建,往往使用第三种,类的名字在写源程序时不需要知道,到运行时再传递过来 6 Class.forName("java.lang.String");
import java.lang.reflect.*; public class DumpMethods { public static void main(String args[]) { try { Class c = Class.forName("java.util.Stack"); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString()); } catch (Throwable e){ System.err.println(e); } } }
1 public synchronized java.lang.Object java.util.Stack.pop() 2 public java.lang.Object java.util.Stack.push(java.lang.Object) 3 public boolean java.util.Stack.empty() 4 public synchronized java.lang.Object java.util.Stack.peek() 5 public synchronized int java.util.Stack.search(java.lang.Object)
1 void printClassName(Object obj) { 2 System.out.println("The class of " + obj + 3 " is " + obj.getClass().getName()); 4 }
1 System.out.println("The name of class Foo is: "+Foo.class.getName());
//获得类类型的两种方式 Class cls1 = Role.class; Class cls2 = Class.forName("yui.Role");
1 Object o = cls1.newInstance(); 2 //创建一个实例 3 //Object o1 = new Role(); //与上面的方法等价
public class TestReflect { public static void main(String[] args) { // TODO Auto-generated method stub String str = "abc"; Class cls1 = str.getClass(); Class cls2 = String.class; Class cls3 = null;//必须要加上null try { cls3 = Class.forName("java.lang.String"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(cls1==cls2); System.out.println(cls1==cls3); System.out.println(cls1.isPrimitive()); System.out.println(int.class.isPrimitive());//判定指定的 Class 对象是否表示一个基本类型。 System.out.println(int.class == Integer.class); System.out.println(int.class == Integer.TYPE); System.out.println(int[].class.isPrimitive()); System.out.println(int[].class.isArray()); } } /* * true true false true false true false true */ */
1 public class TestReflect { 2 public static void main(String[] args) throws SecurityException, NoSuchMethodException { 3 // TODO Auto-generated method stub 4 String str = "abc"; 5 6 System.out.println(String.class.getConstructor(StringBuffer.class)); 7 } 8 }
1 import java.lang.reflect.Field; 2 public class TestReflect { 3 public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception { 4 ReflectPointer rp1 = new ReflectPointer(3,4); 5 Field fieldx = rp1.getClass().getField("x");//必须是x或者y 6 System.out.println(fieldx.get(rp1)); 7 8 /* 9 * private的成员变量必须使用getDeclaredField,并setAccessible(true),否则看得到拿不到 10 */ 11 Field fieldy = rp1.getClass().getDeclaredField("y"); 12 fieldy.setAccessible(true);//暴力反射 13 System.out.println(fieldy.get(rp1)); 14 15 } 16 } 17 18 class ReflectPointer { 19 20 public int x = 0; 21 private int y = 0; 22 23 public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source 24 super(); 25 // TODO Auto-generated constructor stub 26 this.x = x; 27 this.y = y; 28 } 29 }
1 import java.lang.reflect.Field; 2 public class TestReflect { 3 public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception { 4 ReflectPointer rp1 = new ReflectPointer(3,4); 5 changeBtoA(rp1); 6 System.out.println(rp1); 7 8 } 9 10 private static void changeBtoA(Object obj) throws RuntimeException, Exception { 11 Field[] fields = obj.getClass().getFields(); 12 13 for(Field field : fields) { 14 //if(field.getType().equals(String.class)) 15 //由于字节码只有一份,用equals语义不准确 16 if(field.getType()==String.class) { 17 String oldValue = (String)field.get(obj); 18 String newValue = oldValue.replace('b', 'a'); 19 field.set(obj,newValue); 20 } 21 } 22 } 23 } 24 25 class ReflectPointer { 26 27 private int x = 0; 28 public int y = 0; 29 public String str1 = "ball"; 30 public String str2 = "basketball"; 31 public String str3 = "itcat"; 32 33 public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source 34 super(); 35 // TODO Auto-generated constructor stub 36 this.x = x; 37 this.y = y; 38 } 39 40 @Override 41 public String toString() { 42 return "ReflectPointer [str1=" + str1 + ", str2=" + str2 + ", str3=" 43 + str3 + "]"; 44 } 45 }
1 import java.lang.reflect.Field; 2 import java.lang.reflect.Method; 3 4 public class TestReflect { 5 public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception { 6 String str = args[0]; 7 /* 8 * 这样会数组角标越界,因为压根没有这个字符数组 9 * 需要右键在run as-configurations-arguments里输入b.Inter(完整类名) 10 * 11 */ 12 Method m = Class.forName(str).getMethod("main",String[].class); 13 //下面这两种方式都可以,main方法需要一个参数 14 15 m.invoke(null, new Object[]{new String[]{"111","222","333"}}); 16 m.invoke(null, (Object)new String[]{"111","222","333"});//这个可以说明,数组也是Object 17 /* 18 * m.invoke(null, new String[]{"111","222","333"}) 19 * 上面的不可以,因为java会自动拆包 20 */ 21 } 22 } 23 24 class Inter { 25 public static void main(String[] args) { 26 for(Object obj : args) { 27 System.out.println(obj); 28 } 29 } 30 }
class S { } public class IsInstance { public static void main(String args[]) { try { Class cls = Class.forName("S"); boolean b1 = cls.isInstance(new Integer(37)); System.out.println(b1); boolean b2 = cls.isInstance(new S()); System.out.println(b2); } catch (Throwable e) { System.err.println(e); } } }
에 해당하는 기본 클래스의 바이트코드를 나타냅니다.
6. 결론
위 내용은 리플렉션 메커니즘의 간단한 사용입니다. 분명히 Spring을 공부한 친구들은 객체를 생성할 때 지정된 메서드와 변수를 얻을 수 있는 이유를 이해해야 합니다. 문자열 구현은 다음과 같습니다. 귀하가 필요로 하는 것을 우리가 제작해 드리고 있으며, Object를 사용하고 있는데, 이는 Java 언어의 동적 특성과 의존성이 크게 감소되었음을 보여줍니다.
자바를 배우는 학생들 주목! ! !
학습 과정에서 문제가 발생하거나 학습 리소스를 얻고 싶다면 Java 학습 교류 그룹 159610322에 가입하세요. 함께 Java를 배우자!
위 내용은 Java 반사 메커니즘에 대한 심층 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!