反射可以直接获得class对象,可以实现动态创建对象
1、调用类的class属性
> Class<?> cls = String.class;//获得String的class对象 > System.out.println("String的class对象:"+cls); cls = > int.class;//获得int类型的class对象 System.out.println("int的class对象:"+cls);输出:
String的class对象:class java.lang.String int的class对象:int
2、调用class中的forName(全类名)方法获得
try { Class<?> cls2 = Class.forName("java.util.Arrays"); System.out.println("Arrays的class对象:"+cls2); //从控制台输入一个类名,获得该类名对应的类对象 Scanner sca = new Scanner(System.in); String className = sca.nextLine();//给的是全类名 Class<?> cls3 = Class.forName(className); System.out.println(className+"的classs对象"+cls3); sca.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }输出:
Arrays的class对象:class java.util.Arrays java.lang.Double java.lang.Double的classs对象class java.lang.Double
完整代码:
public class ReflectDemo01 { public static void main(String[] args) { //"?"通配符,不论什么类型都能匹配 Class<?> cls = String.class;//获得String的class对象 System.out.println("String的class对象:"+cls); cls = int.class;//获得int类型的class对象 System.out.println("int的class对象:"+cls); try { Class<?> cls2 = Class.forName("java.util.Arrays"); System.out.println("Arrays的class对象:"+cls2); //从控制台输入一个类名,获得该类名对应的类对象 Scanner sca = new Scanner(System.in); String className = sca.nextLine();//给的是全类名 Class<?> cls3 = Class.forName(className); System.out.println(className+"的classs对象"+cls3); sca.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }1、先创建一个类person
class Person{ private String name; private Integer age; private String sex; public Person() {} public Person(String name, Integer age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }2、获得Class对象
//获得class对象 Class<?> cls = Class.forName("reflect.Person");3、创建实例 (1)通过无参构造创建的实例
Object instance = cls.newInstance(); System.out.println("无参构造创建对象:"+instance);//默认调用类中的toString()方法输出:因为是无参构造,所以里面是空的
无参构造创建对象:Person [name=null, age=null, sex=null]
(2)通过有参构造创建实例 先获得构造函数,使用getConstructor(parameterTypes)方法,参数是构造函数参数的类型的class对象,是可变参数
Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);然后使用构造函数创建对象
Object o2 = con.newInstance("有参构造创建对象:"+"张三",100,"男"); System.out.println(o2);输出:
Person [name=有参构造创建对象:张三, age=100, sex=男]
完整代码
public class RefiectDemo02 { public static void main(String[] args) { try { //获得class对象 Class<?> cls = Class.forName("reflect.Person"); /** * 通过无参构造创建的对象实例 */ Object instance = cls.newInstance(); System.out.println("无参构造创建对象:"+instance);//默认调用类中的toString()方法 /** * 通过有参构造方法创建对象 */ Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class);//这里的参数是class类型的可变参数 Object o2 = con.newInstance("有参构造创建对象:"+"张三",100,"男"); System.out.println(o2); } catch (Exception e) { e.printStackTrace(); } } } class Person{ private String name; private Integer age; private String sex; public Person() {} public Person(String name, Integer age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }1、获得class对象
//获得类对象 Class<?> cls = Class.forName("reflect.Person");2、获得方法 (1)getMethods()方法获得class对象对应的类中的所有的非私有方法,包括继承过来的方法
Method[] methods = cls.getMethods(); for(Method m : methods) { //直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型 //getName()获得方法的名字 System.out.println(m.getName()); }输出结果 (2)getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用),第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数,方法没有参数不用传第二个参数
//获得有参构造函数 Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class); //根据有参构造创建对象 Object o = con.newInstance("李四",23,"女");获得person类中的getName()方法
Method getName = cls.getMethod("getName");调用类中的方法使用invoke()方法,调用之前需要先创建对象
Object s = getName.invoke(o);//得到方法的返回值 System.out.println(s);输出
李四
获得person类中的setName()方法
Method setName = cls.getMethod("setName",String.class); Object s2 = setName.invoke(o, "王五");//得到方法的返回值 System.out.println(s2);输出:因为set方法没有返回值,所以输出为null
null
完整代码
public class ReflectDemo03 { public static void main(String[] args) { try { //获得类对象 Class<?> cls = Class.forName("reflect.Person"); //getMethods()获得类对象对应的类中的所有的方法 Method[] methods = cls.getMethods(); for(Method m : methods) { //直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型 //getName()获得方法的名字 System.out.println("具体信息:"+m); System.out.println("方法名:"+m.getName()); } /** * getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用), * 第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数 * 方法没有参数不用传第二个参数 */ Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class); Object o = con.newInstance("李四",23,"女"); //获得方法 Method getName = cls.getMethod("getName"); //调用方法使用invoke()方法,调用之前需要先创建对象 Object s = getName.invoke(o);//得到方法的返回值 System.out.println(s); Method setName = cls.getMethod("setName",String.class); Object s2 = setName.invoke(o, "王五");//得到方法的返回值 System.out.println(s2); } catch (Exception e) { e.printStackTrace(); } } }先创建一个测试类
class Test{ private void test1() { System.out.println("私有方法1"); } public void test2() { System.out.println("公有方法1"); } }获得class对象
Class<?> cls = Test.class;getDeclaredMethods()可以获得类中所有定义的方法,不包含继承过来的方法
Method[] methods2 = cls.getDeclaredMethods(); for(Method m:methods2) { System.out.println(m.getName()); }输出:
test1 test2
根据方法名字获得类中的私有方法,然后创建对象,使用setAccessible(boolean b)方法,参数为true即可把私有方法设置方法为可访问
Method method = cls.getDeclaredMethod("test1"); //获得根据无参构造创建的类对象 Object o = cls.newInstance(); //setAccessible(boolean b)参数为true即可把私有方法设置方法为可访问 method.setAccessible(true); method.invoke(o);完整代码
public class ReflectDemo03 { public static void main(String[] args) { try { //获得类对象 Class<?> cls = Class.forName("reflect.Person"); //getMethods()获得类对象对应的类中的所有的方法 Method[] methods = cls.getMethods(); for(Method m : methods) { //直接输出m的话会输出每个方法的具体信息,包括修饰权限和返回值类型 //getName()获得方法的名字 System.out.println("具体信息:"+m); System.out.println("方法名:"+m.getName()); } /** * getName(methodName,paraType)根据方法名获得方法(有多个重载方法使用), * 第一个参数是方法名,第二个参数是方法里面的参数类型的class对象,是可变参数 * 方法没有参数不用传第二个参数 */ Constructor<?> con = cls.getConstructor(String.class,Integer.class,String.class); Object o = con.newInstance("李四",23,"女"); //获得方法 Method getName = cls.getMethod("getName"); //调用方法使用invoke()方法,调用之前需要先创建对象 Object s = getName.invoke(o);//得到方法的返回值 System.out.println(s); Method setName = cls.getMethod("setName",String.class); Object s2 = setName.invoke(o, "王五");//得到方法的返回值 System.out.println(s2); } catch (Exception e) { e.printStackTrace(); } } }