(一)认识反射
反射:对象的反象处理.所谓"反"是指根据对象来取得对象的来源信息,而这个"反"操作核心处理的就在于Object类的一个方法:
1.取得Class类对象
public final native Class<?> getClass();
示例:
public class Test {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date.getClass());
}
}
在反射中,看重的不是对象,而是身后的组成(类,构造,普通,成员等)
2.实例化对象:
(1)任何类的实例化对象都可以通过Object类中的getCLass()方法取得;
(2)"类.class":直接提供具体类来取得类的实例化对象.
(3)使用Class类提供的方法:public static Class<?> forName(String className);
示例:
(2)
class Person{
private String name;
}
public class Test {
public static void main(String[] args) {
System.out.println(Person.class);
}
}
(3)
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> slc = Class.forName("java.util.Date");
System.out.println(slc.getName());
}
}
反射实例化对象:
public class Test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> slc = Class.forName("java.util.Date");
Object object = slc.newInstance();//实例化
System.out.println(object);
}
}
(二)反射与类的操作
注:利用反射可以做出一个对象具备的所有操作行为,最为关键的是这一切的操作都基于Object类
1.获取父类信息
在java中任何程序类一定有父类,在Class类中就可以通过该方法获取父类或者实现的父接口:
获取类的包名称:public Package getPackage();
获取父类的Class对象:public native Class<? super T> getSuperClass();
获取实现的父接口:public Class<?>[] getInterfaces();
interface IFruit{}
interface IMessage{}
class CLS implements IFruit,IMessage{}
public class Test {
public static void main(String[] args) {
Class<?> cls = CLS.class;
//取得类的包名称
System.out.println(cls.getPackage().getName());
//取得父类的名称
System.out.println(cls.getSuperclass().getName());
//取得实现接口的对象
Class<?>[] classes = cls.getInterfaces();
for (Class<?> classes1:classes){
System.out.println(classes1);
}
}
}
2.反射调用构造方法:
(1)取得指定参数的构造方法:
public Constructor<T> getConstructor(Class<?>...parameterTypes);
(2)取得类中所有的构造方法:
public Constructor<T>[] getConstructor();
class Person{
public Person(){}
public Person(String name){}
public Person(String name,int age){}
}
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Class<?> cls = Person.class;
//指定参数类型构造
Constructor<?> constructor = cls.getConstructor(String.class,int.class);
System.out.println(constructor);
//所有参数类型构造
Constructor<?>[] constructors = cls.getConstructors();
for (Constructor<?> constructor1:constructors){
System.out.println(constructor1);
}
}
}
注:在定义简单Java类是一定要保留一个无参数的构造.
Class类通过反射实例化类对象的时候,只能调用类中的无参构造.如果类中没有无参构造则无法使用Class类调用,只能通过明确的构造调用实例化处理.
3.反射调用普通方法:
(1)取得全部普通方法:
public Method[] getMethod();
(2)取得指定普通方法:
public Method[] getMethod(String name,Class<?>...paramaterTypes);
class Person{
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person [name="+this.name+" "+"age="+this.age+"]";
}
}
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Class<?> cls = Person.class;
//取得指定普通方法
Method method = cls.getMethod("setName", String.class);
System.out.println(method);
//取得全部普通方法
Method[] methods = cls.getMethods();
for (Method methods1:methods){
System.out.println(methods1);
}
}
}
4.反射调用类属性:
父类中:
(1)取得全部属性:public Field[] getFields();
(2)取得类中指定名称属性:public Field[] getFields(String name);
子类中:
(1)取得全部属性:public Field[] getDeclaredFields();
(2)取得类中指定名称属性:public Method getDeclaredFields(String name,Class<?>...parameterTypes);
class Person{
private String name;
}
class Student extends Person{
private int age;
}
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> cls = Class.forName("exicise.Student");
//获取父类的的全部属性
{
Field[] fields = cls.getFields();
for (Field field:fields){
System.out.println(field);
}
}
//获取本类中的所有属性
System.out.println("____________");
{
Field[] fields = cls.getDeclaredFields();
for (Field field:fields){
System.out.println(field);
}
}
}
}
注:类中所有属性必须在类对象实例化之后才进行空间分配,若想调用类中属性,必须保持实例化对象.
class Person{
private String name;
}
public class Test {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
Class<?> cls = Class.forName("exicise.Person");
Object object = cls.newInstance();//实例化
Field nameField = cls.getDeclaredField("name");//操作属性
nameField.set(object,"Bob");
System.out.println(nameField.get(object));//取得属性
}
}
本文深入解析Java反射机制,包括如何通过反射获取类信息、实例化对象、调用构造方法、普通方法及类属性,展示了反射在Java编程中的强大功能。
1098

被折叠的 条评论
为什么被折叠?



