什么是反射
可以访问类中的所有属性、方法、构造方法,像一面镜子,还可以创建一个对象对封装的类里面的东西进行使用
详细参考连接
获取class对象的四种方法
通过Class.forName、类名.class、对象的getClass和基础类型的TYPE,第一种和第二种推荐,第三种不推荐
public class CreateClassObject {
public static void main (String[] args) throws ClassNotFoundException {
//1、通过class.forname()来获取Class对象,只需要知道类的完全限定名
// Class clazz = Class.forName("entity.Emp"); // 参数为类的完全限定名:全限定名 = 包名+类名
//2、通过类名.class来获取,需要项目里有这个类的包
// Class<Emp> clazz = Emp.class;
//3、通过对象的getClass()来获取,需要再创建一个对象,资源的一个复用,不推荐
Class clazz = new Emp().getClass ();
System.out.println (clazz.getPackage ());
System.out.println (clazz.getName ());
System.out.println (clazz.getSimpleName ());
System.out.println (clazz.getCanonicalName ());
//4、如果是一个基本数据类型,那么可以通过Type的方式来获取Class对象
Class type = Integer.TYPE;
//???
System.out.println (type.getName ());
System.out.println (type.getCanonicalName ());
}
}
ClassAPI实例
public class ClassAPI {
public static void main(String[] args) throws Exception{
Class<?> clazz = Class.forName("com.mashibing.reflect.Student");
//获取成员变量,包括子类及父类,同时只能包含公共的方法
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
System.out.println(field.getName());
System.out.println(field.getType());
System.out.println(field.getModifiers());
System.out.println("-----");
}
System.out.println("=======================");
//此方法返回的是当前类的所有属性,不仅仅局限于公共访问修饰符,所有的访问修饰符都可以拿到
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
System.out.println("========================");
//反射在一定程度上破坏了封装性,需要合理使用
Field address = clazz.getDeclaredField("address");
//设置该属性是否能被访问,true表示能被访问,破坏了封装性
address.setAccessible(true);
System.out.println(address.getName());
Object o = clazz.newInstance();
address.set(o,"北京市");
System.out.println(((Student)o).getAddress());
System.out.println("===============================");
//获取该对象的普通方法,包含的方法范围是当前对象及父类对象的所有公共方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
System.out.println("-----------------------");
//获取当前类中所有的方法,无论什么访问修饰符
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
System.out.println("--------------");
Method add = clazz.getDeclaredMethod("add", int.class, int.class);
add.setAccessible(true);
Object o1 = clazz.newInstance(); // instance调用该方法的类的无参构造方法
add.invoke(o1,123,123);
System.out.println("----------------------");
//获取对象的所有构造方法,只能获取公有的改造方法
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.getName());
}
System.out.println("--------------");
//获取所有的构造方法,无论是私有还是公有
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor.getName());
}
//调用私有的构造方法
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Student o2 = (Student)declaredConstructor.newInstance("msb", 23, "java");
System.out.println(o2);
}
}
Person类
public class Person {
public String name;
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String show(){
return "name:"+name+", age :"+age;
}
}
Student类
public class Student extends Person{
public String className;
private String address;
public Student(){
super();
}
private Student(String name,int age,String className){
super(name,age);
this.className= className;
}
public Student(String name,int age,String className,String address){
super(name,age);
this.className = className;
this.address = address;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
private void add(int a,int b){
System.out.println(a+b);
}
@Override
public String toString() {
return "Student{" +
"className='" + className + '\'' +
", address='" + address + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}