Rumah >Java >javaTutorial >Cara menggunakan refleksi Java dan analisis contoh
Sesuatu objek boleh mendapatkan kelasnya melalui refleksi, dan kelas boleh memperoleh semua kaedah (termasuk Persendirian) Anda boleh mengendalikan fail bytecode melalui mekanisme pantulan dalam bahasa java, dan anda boleh membaca dan mengubah suai fail bytecode
hanya perlu mengetahui nama kelas dan kod instance akan digunakan semasa memuatkan JDBC
public class test1 { public static void main(String[] args) throws ClassNotFoundException { Class name = Class.forName("java.lang.Runtime"); System.out.println(name); } }
Gunakan .class
untuk mendapatkan objek
public class test1 { public static void main(String[] args) throws ClassNotFoundException { Class<?> name = Runtime.class; System.out.println(name); } }
getClass untuk mendapatkan objek bytecode, anda mesti menentukan kelas tertentu dan kemudian mencipta objek
public class test1 { public static void main(String[] args) throws ClassNotFoundException { Runtime rt = Runtime.getRuntime(); Class<?> name = rt.getClass(); System.out.println(name); } }
Kaedah ini serupa dengan forName, selagi terdapat nama kelas, tetapi perbezaannya ialah JVM statik forName akan memuatkan kelas dan Jalankan kod dalam static()
public class getSystemClassLoader { public static void main(String[] args) throws ClassNotFoundException { Class<?> name = ClassLoader.getSystemClassLoader().loadClass("java.lang.Runtime"); System.out.println(name); } }
import java.lang.reflect.Method; public class getDeclaredMethods { public static void main(String[] args) throws ClassNotFoundException { Class<?> name = Class.forName("java.lang.Runtime"); System.out.println(name); Method[] m = name.getDeclaredMethods(); for(Method x:m) System.out.println(x); } }
b getDeclaredMethod
import java.lang.reflect.Method; public class getDeclaredMethod { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException { Class<?> name = Class.forName("java.lang.Runtime"); Method m = name.getDeclaredMethod("exec",String.class); System.out.println(m); } }c. getMethods mengembalikan Semua kaedah awam kelas, termasuk kaedah awam kelas yang diwarisi d getMethod parameter adalah sama dengan getDeclaredMethod
Dengan cara yang sama, kaedah Kaedah
dapatkan semua tatasusunan pembolehubah ahli kelas, tetapi lakukan. tidak termasuk kelas induk
Dapatkan khusus, parameter ialah nama kaedah yang dikehendaki
Pembina>[] getConstructors(): hanya mengembalikan pembina awam
Pembina getConstructor (Kelas >... parameterTypes): Padan dengan pembina awam Constructor getDeclaredConstructor (Kelas >... parameterTypes): Padanan dan parameter Parameter pembina yang sepadan dengan jenis padananialah objek kelas jenis parameter kaedah, serupa dengan Kaedah, seperti
5. Reflection mencipta objek kelas
newInstanceString.class
Class c = Class.forName("com.reflect.MethodTest"); // 创建Class对象 Object m1 = c.newInstance(); // 创建类对象
kaedah invokenewInstance()
public Object invoke(Object obj, Object... args)
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Invoke { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class c = Class.forName("Invoke"); Object o = c.newInstance(); Method m = c.getMethod("test"); m.invoke(o); } public void test(){ System.out.println("测试成功"); } }tetapi ralat ditemui Sebab masalah ini:
Pembina kelas yang digunakan adalah peribadiKelas yang digunakan tidak mempunyai pembina tanpa parameter
, gunakan ini untuk memecahkan sekatan akses
Java.lang.reflect.AccessibleObject类是Field,Method和Constructor类对象的基类,可以提供将反射对象标记为使用它抑制摸人Java访问控制检查的功能,同时上述的反射类中的Field,Method和Constructor继承自AccessibleObject。所以我们在这些类方法基础上调用setAccessible()方法,既可对这些私有字段进行操作
简单来说,私有的属性、方法、构造方法,可以通过这个去突破限制,xxx.setAccessible(true)
可以看到Runtime的构造方法是private的
那么这里我们就可以这么去突破限制 先获取构造方法,然后setAccessible获取访问权限 然后再最后invoke里面,第一个参数写成con.newInstance()
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Exec { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Class c = Class.forName("java.lang.Runtime"); Constructor con = c.getDeclaredConstructor(); con.setAccessible(true); Method m = c.getMethod("exec",String.class); m.invoke(con.newInstance(),"/System/Applications/Calculator.app/Contents/MacOS/Calculator"); } }
这里有一个疑问,如果把con.newInstance单独提取出来,他打开计算器不会显示出来,但是后台的确是启动了,不知道啥原因
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Exec { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Class c = Class.forName("java.lang.Runtime"); Constructor con = c.getDeclaredConstructor(); con.setAccessible(true); Object o = con.newInstance(); Method m = c.getMethod("exec",String.class); m.invoke(o,"/System/Applications/Calculator.app/Contents/MacOS/Calculator"); } }
反射中常用的几个重要方法:
获取类的⽅法: forName
实例化类对象的⽅法: newInstance
获取函数的⽅法: getMethod
执⾏函数的⽅法: invoke
限制突破方法:setAccessible
Atas ialah kandungan terperinci Cara menggunakan refleksi Java dan analisis contoh. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!