一个类如果想被使用,要先加载到内存中,一般会经过以下步骤,第二步还可以细分为三步。
类加载器用来把类的二进制文件加载到内存中,并在堆区生成一个与之对应的java.lang.Class对象.
类加载器通常由JVM提供,其加载的类文件的来源有以下几种:
类加载器的组成层次:
详细可见类的加载
反射的机制:
能通过一个Class对象操作类的成员,一旦能得到类的Class对象,就可以通过它来使用其所对应的类的任意成员变量,构造方法以及成员方法。
所以,Class对象中,最基本的应该包含三个方面内容:
3、
eg:Class.forName(“com.test.Student”)
获取所有或公共构造方法
public Constructor[] getConstructors()//获取所有的公共构造
public Constructor[] getDeclaredConstructors()//获取所有的构造
获取指定构造方法并使用
public Constructor getConstructor(Class... types)//获取指定的公共构造
public Constructor getDeclaredConstructor(Class... types)//获取指定的构造
Class c = Class.forName("com.test.Person"); Constructor con = c.getConstructor();//获取空参构造方法 Object obj = con.newInstance();//创建对象 Class c = Class.forName("com.Person"); Constructor con = c.getConstructor(String.class,int.class); Object obj = con.newInstance(“tom”,11); Class c = Class.forName(“com.Person”); Constructor con = c.getDeclaredConstructor(String.class); Object obj = con.newInstance(11);
5.1案例暴力破解私有方法
class Student { private String name; public int age; //各种权限的构造方法 public Student(){ System.out.println("空参构造"); } Student(String name){ this.name = name; System.out.println("带字符串的构造方法"); } public Student(int age){ this.age = age; System.out.println("带int的构造方法"); } private Student(Long l){ System.out.println("私有的构造方法被调用"); this.name = "zhangsan"; this.age = 20; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } // public void test1(){ System.out.println("无参无返回值方法"); } public void test2(int i){ System.out.println("有参无返回值方法"); } public String test3(String name){ System.out.println("有参有返回值方法"); return name; } private void test4(){ System.out.println("私有的无参无返回值方法"); } } import java.lang.reflect.Constructor; public class Demo2 { public static void main(String[] args) throws Exception { //获取Class对象 Class c1 = Class.forName("com.test11.reflect.Student"); //获取私有构造方法 Constructor con = c1.getDeclaredConstructor(Long.class); //(设置可访问性)暴力破解 con.setAccessible(true); //创建对象 Object obj = con.newInstance(10L); Student s = (Student) obj; System.out.println(s.getName() +"--"+ s.getAge()); } }
import java.lang.reflect.Constructor; import java.lang.reflect.Field; /* * 成员变量的使用 */ public class Demo3 { public static void main(String[] args) throws Exception { // Class c = Class.forName("wang.Student"); Constructor con = c.getDeclaredConstructor(); Object obj = con.newInstance(); //获取所有的公共字段 // Field[] fields = c.getFields(); // for (Field f : fields) { // System.out.println(f); // } //结果:public int wang.Student.age //获取所有的字段 Field[] fields = c.getDeclaredFields(); for (Field f : fields) { System.out.println(f); } //结果: //private java.lang.String wang.Student.name //public int wang.Student.age //获取指定的字段 Field f = c.getDeclaredField("name"); //设置可访问性 f.setAccessible(true); //使用成员变量 f.set(obj, "李四"); //查看结果 System.out.println(((Student)obj).getName());//李四 } }
import java.lang.reflect.Constructor; import java.lang.reflect.Method; /* * 成员方法的使用 */ public class Demo4 { public static void main(String[] args) throws Exception { Class c = Class.forName("com.test11.reflect.Student"); Constructor con = c.getDeclaredConstructor(); Object obj = con.newInstance(); //获取所有公共的成员方法 // Method[] ms = c.getMethods(); // for (Method m : ms) { // System.out.println(m); // } //获取所有成员方法 // Method[] ms = c.getDeclaredMethods(); // for (Method method : ms) { // System.out.println(method); // } //获取指定的方法 // Method m = c.getDeclaredMethod("test3", String.class); // //设置可访问性 // m.setAccessible(true); // //使用成员方法 // Object res = m.invoke(obj, "string"); // System.out.println(((String)res).toUpperCase()); //获取没有参数的方法并使用 Method m = c.getDeclaredMethod("test4"); m.setAccessible(true); Object res = m.invoke(obj);//没有返回值的方法,返回的是null System.out.println(res); } }
法1:从配置文件中读取到类名
法2:使用类加载器的方式获取配置文件内容
法3:通过ResourceBundle获取配置文件内容
import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Constructor; import java.util.Properties; import java.util.ResourceBundle; /* * 创建对象的工作由工厂来做 * */ public class AnimalFactory { //私有化构造方法,外界不能创建对象,只能通过静态方法获取Animal对象 private AnimalFactory(){} public static Animal getAnimal() throws Exception{ //法1:从配置文件中读取到类名 // Properties p = new Properties(); // p.load(new FileInputStream("config.txt")); // String className = p.getProperty("className"); //法2:使用类加载器的方式获取配置文件内容 // InputStream in = AnimalFactory.class.getClassLoader().getResourceAsStream("config.txt"); // Properties p = new Properties(); // p.load(in); // String className = p.getProperty("className"); //法3:通过ResourceBundle获取配置文件内容 ResourceBundle b = ResourceBundle.getBundle("a"); String className = b.getString("className"); //获取到类名对应的Class对象 Class c = Class.forName(className); //获取到空参构造方法并调用 Constructor con = c.getDeclaredConstructor(); Object obj = con.newInstance(); return (Animal)obj; } }
原文:https://www.cnblogs.com/wqbin/p/11215934.html