所有的有关反射的东西都在java.lang.reflect包下,在java.lang包下的所有东西都不需要导包
获取Class对象
所有的反射操作都是基于Class对象来进行的,所以获取Class对象非常关键
有三种获取的方法
利用getClass()方法进行获取,自定义类亦可以使用,因为他是封装在Object类中,所有的类都默认继承Object类,需要使用对象名调用利用Class类中的class属性,java中所有的数据类型都有class属性,注意:一定要使用类名来获取属性,使用对象名无法获取到class属性使用Class类中的静态方法forName()方法并传入类的全类名即可得到
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
//方法一
Class stuClass = stu.getClass();//使用对象名调用
System.out.println(stuClass.getName());
//方法二
Class stuClass2 = Student.class;//直接使用类名调用
System.out.println(stuClass2.getName());
System.out.println(stuClass == stuClass2);//结果为true表示获取到的是同一个class对象
//方法三
Class stuClass3 = Class.forName("pojo.Student");
System.out.println(stuClass3.getName());
System.out.println(stuClass == stuClass3);//结果为true表示仍然是同一个class对象
}
}
根据对象地址的判断,我们可以发现,这三种方法获取到的Class对象都是用同一个对象
问题:如果我们并不是同一个对象然后使用getClass方法还能获取到同一个对象吗?
import pojo.Student;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
Student stu = new Student();
Student stu1 = new Student();
Class aClass = stu.getClass();
Class aClass1 = stu1.getClass();
System.out.println(aClass == aClass1);
}
}
根据结果我们就可以得到无论有多少个对象,获取到的class对象都只有一个
获取包名+类名使用getName()方法
使用Class类中的getName()方法即可获取类名+包名,为了让大家清楚,我创建一个Abc类放在pojo包下,我们完全可以不给这个类中书写任何内容直接进行测试
public class Demo {
public static void main(String[] args) {
Abc abc = new Abc();
Class abcClass = abc.getclass();
System.out.println(abcClass.getName());
}
}
获取构造函数
首先编写一个实体类,其中包含六种构造函数
Student(String str){}//默认构造
public Student(){}//公有无参构造
public Student(int x){}//有一个参数的构造
public Student(int x,char a){}//有多个参数的构造方法
protected Student(char x){}//保护的构造
private Student(boolean x){}//私有构造
然后进行测试
public class Demo {
public static void main(String[] args) {
Class stu = Class.forName("pojo.Student");
//获取所有的公有构造方法
Constructor[] constructors = stu.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------------------------------------");
//获取所有的构造方法
Constructor[] declaredConstructors = stu.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("-------------------------------------");
//获取公有、无参的构造方法
Constructor constructor = stu.getConstructor(null);
System.out.println(constructor);
//使用newInstance方法可以直接根据这个构造器创建一个对象
Object o = constructor.newInstance();
System.out.println("-------------------------------------");
//获取私有构造方法
Constructor declaredConstructor = stu.getDeclaredConstructor(char.class);//传入的是什么类型的class,那么得到的私有构造方法就是这种类型的参数
System.out.println(declaredConstructor);
}
}
//输出结果
获取属性的方法
同样的先编写实体类
//由于java的修饰符只有四种于是我们只需要测试四种即可 public int a; char b; protected int c; private String name; private Integer age;
测试
public class Demo {
public static void main(String[] args){
Class stu = Class.forName("pojo.Student");
//获取所有的公有字段
Field[] fields = stu.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-------------------------------------");
//获取所有的字段
Field[] declaredFields = stu.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
System.out.println("-------------------------------------");
//获取其中一个公有字段
Field a = stu.getField("a");
System.out.println(a);
System.out.println("-------------------------------------");
//获取其中的私有字段
Field name = stu.getDeclaredField("name");
System.out.println(name);
}
}
获取成员方法
实体类
public void show1(String s){}
protected void show2(){}
void show3(){}
private String show4(int age) {}
测试
public class Demo {
public static void main(String[] args){
Class stu = Class.forName("pojo.Student");
//获取对象
Object o = stu.getConstructor().newInstance();
//获取所有公有方法
Method[] methods = stu.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("--------------------------------");
//获取所有的方法
Method[] declaredMethods = stu.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("--------------------------------");
//获取公有方法
Method show1 = stu.getMethod("show1", String.class);
System.out.println(show1);
//使用这个方法
show1.invoke(o,"123");
System.out.println("--------------------------------");
//获取私有方法
Method show4 = stu.getDeclaredMethod("show4", int.class);
System.out.println(show4);
}
}
从输出结果看出,java的类都默认继承Object类



