思考:
在Java运行环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?
什么是反射机制?
简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
利用反射机制能获得什么信息?
一句话,类中有什么信息,它就可以获得什么信息,不过前提是得知道类的名字,要不就没有后文了首先得根据传入的类的全名来创建Class对象。
获取Class对象的三种方式
- 对象名.getClass()
- 类名.class
- Class.forName
package ReflectDemo;
public class Person {
private int id;
private String name;
public Person() {
super();
}
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package ReflectDemo;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//获取Class对象的三种方式
Class c1 = null;
Class c2 = null;
Class c3 = null;
//1、类名.class
c1 = Person.class;
//2、Class.forName(包名.类名)
c2 = Class.forName("ReflectDemo.Person");
//3、对象名.getClass()
Person person = new Person();
c3 = person.getClass();
//打印测试
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
}
}
实例化对象:
1、以前的做法:类名 对象名 = new 类名();
2、反射做法:
Class<?> c1 = Class.forName("com.lanqiao.demo3.Person");
Person per1 = (Person)c1.newInstance();
package ReflectDemo;
public class Test {
public static void main(String[] args) throws Exception {
//反射获取对象的写法:
Class c = Class.forName("ReflectDemo.Person");
Person person = (Person) c.newInstance();
System.out.println(person);
}
}
通过反射获取构造方法:
package ReflectDemo;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) throws Exception {
//反射获取对象的写法:
Class c = Class.forName("ReflectDemo.Person");
//获取所有构造方法
Constructor[] constructors = c.getConstructors();
//遍历
for (int i = 0; i < constructors.length; i++) {
System.out.println(constructors[i]);
}
//执行构造方法
Person person = (Person) constructors[1].newInstance(new Object[]{18,"张文"});
System.out.println(person.getId()+"\t"+person.getName());
}
}
获取类中的属性及执行操作
package ReflectDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class c = Class.forName("ReflectDemo.Person");
//2.实例化具体对象
Person person = (Person) c.newInstance();
//3.获取类中的所有属性
Field[] fs = c.getFields();//只能查看自身以及父类中的公共的(public)属性,私有化属性看不到
for (int i = 0; i < fs.length; i++) {
System.out.println(fs[i].getName());
}
System.out.println("====");
Field[] fs1 = c.getDeclaredFields();//这个方法只能获取本类的属性,包括私有公有,但是父类中的看不到
for (int i = 0; i < fs1.length; i++) {
System.out.println(fs1[i].getName());
}
}
}
获取指定属性并且设置属性
package ReflectDemo;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class c = Class.forName("ReflectDemo.Person");
//2.实例化具体对象
Person person = (Person) c.newInstance();
//3.获取类中的指定属性
Field field = c.getDeclaredField("name");
//因为属性私有化,这个方法是破解封装性,才能操作属性
field.setAccessible(true);
//设置属性值
field.set(person, "测试名");
//获取属性值
String name = field.get(person).toString();
System.out.println(name);
}
}
获取类中的方法以及执行的操作
package ReflectDemo;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class c = Class.forName("ReflectDemo.Person");
//2.实例化具体对象
Person person = (Person) c.newInstance();
//3.获取所有的方法
/**
* getMethods()方法是获取当前类以及父类中所有的公开的方法
*/
Method[] methods = c.getMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i]);
}
System.out.println("==========");
/**
* getDeclaredMethods()方法是获取当前类中所有的方法,包括私有公有
*/
Method[] methods1 = c.getDeclaredMethods();、
for (int i = 0; i < methods1.length; i++) {
System.out.println(methods1[i]);
}
}
}
获取指定的方法
package ReflectDemo;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class c = Class.forName("ReflectDemo.Person");
//2.实例化具体对象
Person person = (Person) c.newInstance();
//3.获取指定的方法
Method setMethod = c.getDeclaredMethod("setName", new Class[]{String.class});
//4.执行方法
setMethod.invoke(person, new Object[]{"测试名"});
//3.获取指定的方法
Method getMethod = c.getDeclaredMethod("getName", new Class[]{});
//4.执行方法
Object obj = getMethod.invoke(person, new Object[]{});
System.out.println(obj.toString());
}
}
工厂模式结合反射实现对象生成