什么是反射:
反射就是将类的各个组成部分封装为其他对象,这就是反射机制。
我们在编码时定义的类中包括:成员变量,各种方法,构造方法等信息,利用反射技术可以对这个类进行全面的剖析,将这个类的各个组成部分封装为其他的对象。
获取Class对象的方式
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
- 类名.class:通过类名的属性class获取
- 对象.getClass():getClass()方法在Object类中定义着。
- 结论:
同一个字节码文件(xxx.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
(ps:包名不应该出现中文的,此处犯了一个小错误)
package com.lp.reflect反射2;
import com.lp.Domain_reflect2.Person;
public class Reflect {
/**
* 获取class三种方式
*/
public static void main(String[] args) throws Exception {
//第一种:Class.forName("全类名"),返回Class对象
Class aClass = Class.forName("com.lp.Domain_reflect2.Person");
System.out.println(aClass);
//第二种:类名.Class
Class personClass = Person.class;
System.out.println(personClass);
//第三种:对象名.getClass
Person p = new Person();
Class aClass1 = p.getClass();
System.out.println(aClass1);
//结论:无论哪种方法获取的class都是同一种。【字节码文件(.class)】只在内存中加载一次。
if(aClass == personClass && aClass == aClass1 && personClass == aClass1){
System.out.println("666");
}
}
}
package com.lp.Domain_reflect2;
public class Person {
private String name;
private int age;
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
执行结果
获取类中信息
- 成员变量,方法,构造方法等
- 获取这些信息之前先得获取这个类 ,也就是xxx.class
Class对象功能
-
获取成员变量们
- Field [ ] getFields() :获取所有public修饰的成员变量
- Field [ ] getField(String name) 获取指定名称的 public修饰的成员变量
- Field [ ] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
- Field [ ] getDeclaredField(String name)
-
获取构造方法们
- Constructor [ ] getConstructors()
- Constructor[ ] getDeclaredConstructors()
-
获取成员方法们:
- Method[] getMethods()
- Method[] getDeclaredMethods()
注意啦啦啦:(getMethods将返回所有的公共方法,包括从超类继承来的)
-
获取全类名
- String getName()
对这些信息的操作
Field:成员变量
1. 设置值
* void set(Object obj, Object value)
2. 获取值
* get(Object obj)
Constructor:构造方法
* 创建对象:
* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
Method:方法对象
* 执行方法:
* Object invoke(Object obj, Object... args)
* 获取方法名称:
* String getName:获取方法名
终于要来代码了
(我这里继续又犯了个小错误,又出现了汉字)
package com.lp.reflect反射;
import com.lp.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class reflect001 {
public static void main(String[] args) throws Exception {
Class c = Person.class; //获取person的class对象
System.out.println("-------------------获取成员变量---------------------------");
Field [] fields = c.getFields(); //获取class c 的public修饰的成员变量
for (Field field: fields ) { //for循环 遍历所有的public修饰的成员变量
System.out.println(field);
}
Field d = c.getField("name"); //获取指定名字的成员变量
System.out.println(d);
System.out.println("------------------------获取构造函数--------------------------");
Constructor [] constructors = c.getConstructors(); //获取所有的构造(无参加有参)方法
for (Constructor constructor:constructors) {
System.out.println(constructor);
}
Constructor constructor = c.getConstructor(String.class, int.class); //指定参数的构造方法
System.out.println(constructor);
**Object person1 = constructor.newInstance("张三", 25); //constructor可以创建新对象
System.out.println(person1);**
System.out.println("----------------------获取成员方法--------------------------");
Method[] methods = c.getMethods();
for (Method methor: methods) {
System.out.println(methor);
}
Method method_eat = c.getMethod("eat"); //获取指定的成员方法
Person p = new Person();
method_eat.invoke(p); // 执行了eat方法
//System.out.println(method);
System.out.println("----------------------获取全类名--------------------------");
String a = c.getName();
System.out.println(a);
}
}
在这我又新建了一个Person类,上文的那个Person类不同了
package com.lp;
public class Person {
public String name;
public int age;
public String sex;
public String a;
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public void eat(){
System.out.println("执行了Person的吃的方法");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
代码执行结果
(转载或引用请标明出处,谢谢)