Java--反射

本文详细介绍了Java反射机制,包括其核心类Class、Field、Method和Constructor的使用,以及如何通过反射创建对象、访问属性和方法。反射使得Java在运行时能够动态获取和调用类的信息,增强了代码的灵活性。在实际开发中,反射被广泛应用在框架如Hibernate、Spring、MyBatis中,是实现动态性的重要手段。
摘要由CSDN通过智能技术生成
在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制
反射使Java这种 静态编译型的语言具有了动态性。
反射具有看透类的能力,类的信息在反射面前都是透明的(包括private的属性和方法都是可以调用)
Java反射机制主要提供一下功能:
1、在运行时判断任意一个对象所属的类。
2、在运行时构造任意一个类的对象。
3、在运行时判断任意一个类所具有的成员变量和方法。
4、在运行时调用任意一个对象的方法。
学习反射的意义
反射使我们在编译的时候知道类型,而是延迟到运行时获得对象的属性调用对象的方法,是的java具有动态性。
Hibernate、Sping、MyBatis都是基于反射来实现的,可以说没有反射就没有这些框架。

类比学习一下:面向对象抽象过程
众多的人             ---->     Person类
众多学生             ----->   Stundent类
众多的类             ----->   Class类:任何一个类里面都包含这些东西:Field[]、Constructor[]、Method[]
众多的属性         ------>   Field类
众多构造方法      ------>   Constructor类
众多的普通方法   ------>   Method类
private String name;// Field
public Integer age;
class Field{
    修饰符;         //private
    类型;            //String
    变量名字;    // name
}
既然 Class 是描述类的类的类型 ,那类结构里面包含哪些东西呢: Field Constructor Method ,同样这些众多的属性、构造函数、方法也有对应的类类型表示他们。
Java.lang.Class;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Constructor;
对于类型的学习我们可以参考做 月饼的模子 ,什么样模子就可以做出什么大小,图案的月饼。对于 Java 里面的 int 类型是四个字节,那么这个模子就是一个只能存放四个字节的模子,用这个模子做出来的就是 int 类型。同理 Class Field Method Constructor 就分别是类、属性、方法、构造函数的模子。
通过 Class 可以获得类的所有属性Field[]、方法Method[]、构造方法Constructor[]信息。
通过 Field 可以获得属性的名字、类型、修饰符
通过 Method 可以获得方法的名字、参数、返回值。

Class:是反射的核心类
每个类加载到内存后,系统都会有唯一的一份 字节码对象 (Person.class/Student.class字节码对象都是Class这个类的实例)
public void testClass() throws ClassNotFoundException {
    // 1.Class.forName(类路径)
    Class clazz1 = Class. forName( "com.situ.day15.Student");
    // 2.类型.class
    Class clazz2 = Student. class;
    // 3.对象.getClass()
   Student student = new Student();
    Class clazz3 = student.getClass();
   
   System. out.println( clazz1 == clazz2); //true
   System. out.println( clazz1 == clazz3); //true
   
}

Constructor 的反射:
public void testConstructor() {
    Class clazz = Student. class;
    Constructor[] constructors = clazz.getDeclaredConstructors();
    for ( Constructor constructor : constructors) {
     System. out.println( constructor);
     System. out.println( constructor.getName()); //构造方法的名字
     System. out.println( constructor. getModifiers()); //修饰符
   }
}
public  com.situ.day15.Student()
com.situ.day15.Student
1
private  com.situ.day15.Student(java.lang.String)
com.situ.day15.Student
2
@Test
public void testConstructor2() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Class clazz = Student. class;
    //得到指定参数的构造方法
    Constructor constructor = clazz .getDeclaredConstructor(String. class );
   System. out.println( constructor);
    constructor.setAccessible( true); //加上之后就可以访问私有构造方法
    //Student student1 = new Student(" zhansgan ");
   Student student = (Student) constructor.newInstance( "zhansgan");
   System. out.println( student);
}
private  com.situ.day15.Student(java.lang.String)
Student [name=zhansgan]
public void testMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    //Student student = new Student();
    //student.setName(" lisi ");
   
    Class clazz = Class. forName( "com.situ.day15.Student");
    //得到无参构造方法
    Constructor constructor = clazz .getConstructor();
    //调用newInstance实例化对象
   Student student = (Student) constructor.newInstance();
    //student.setName(" lisi ");
   Method method = clazz .getMethod( "setName" , String. class );
    method.invoke( student, "lisi");
   System. out.println( student);
}


利用反射加配置文件加载指定数据库:
Hibernate/MyBatis
public interface  class IDB {
    public abstract void getConnection();
}
public class MySql implements IDB{
    @Override
    public void getConnection() {
      System. out.println( "MySql.getConnection()");
   }
}
public class Oracle implements IDB{
    @Override
    public void getConnection() {
      System. out.println( "Oracle.getConnection()");
   }
}
public class SqlServer implements IDB{
    @Override
    public void getConnection() {
      System. out.println( "SqlServer.getConnection()");
   }
}
public class DBTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
      //IDB db = new MySql();
      //db.getConntion();
      FileInputStream fileInputStream =
           new FileInputStream( "src/com/situ/day15/db/db.properties");
     Properties properties = new Properties();
      properties.load( fileInputStream);
     String className = properties.getProperty( "className");
     System. out.println( className);
      Class clazz = Class. forName( className);
     //  Constructor constructor = clazz .getConstructor();
      // IDB  db = new MySql();
      IDB  db = (AbstractDB) clazz.newInstance();
      db.getConntion();
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值