栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java中的反射机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java中的反射机制

反射

文章目录

反射

总结反射是什么?

Class类

获得类的Class对象 constructor类Field类Method类

总结

要用反射,先获得类的Class对象,

Class c = Class.forName(classpath);
Object user =  c.newInstance();

通过Class对象获得类中的构造方法,将获得的构造方法信息,封装到一个Constructor类的对象中

Constructor constructor =  c.getDeclaredConstructor();

通过Class对象获得类中的属性信息,封装到一个Field类的对象中

Field namef = c.getDeclaredField("属性");

属性是私有的,不能直接操作,通过获取属性公有的get,set方法

通过Class对象获得类中的方法,封装到一个Method类的对象中

Method m = c.getMethod("set"+String.valueOf(s.charAt(0)).toUpperCase()+s.substring(1),String.class);//setNo()
m.invoke(user,"100"); //Invoke 调用
Method m1 = c.getMethod("get"+String.valueOf(s.charAt(0)).toUpperCase()+s.substring(1));//getNo()
             System.out.println(m1.invoke(user));//100

首先,大概有个反射的概念。

反射就是能够在只知道一个类名的情况下,动态获取到类的方法、属性等类中的信息,是让我们来使用的。

理解一下:只知道类名,就能知道类中的方法和属性。

这里回想下之前学的,想要调用类中的属性和方法,是怎么做的?

答:先创建一个类,定义好属性、方法、构造方法等,然后new一个对象出来,最后使用对象调用属性、方法,像下面这样:

①先创建了一个User类:

public class User {
    //属性
    private int no;
    private String name;
    
	//无参构造方法
    public User() {
        System.out.println("无参构造方法");
    }
	//有参构造方法
    public User(int no, String name) {
        this.no = no;
        this.name = name;
        System.out.println("有参构造方法");
    }
    
    //无参成员方法
    public void eat(){
        System.out.println("eat");
    }
    //有参成员方法
    public void eat(String n){
        System.out.println("有参的eat");
    }
    
	//访问私有属性的入口
    public int getNo() {
        System.out.println("getNo");
        return no;
    }
    public void setNo(int no) {
        System.out.println("setNo");
        this.no = no;
    }
    public String getName() {
        System.out.println("getName");
        return name;
    }
    public void setName(String name) {
        System.out.println("setName");
        this.name = name;
    }
}

②再new一个对象,通过对象来调用类中的方法属性:

public class Test {
    public static void main(String[] args){
	    User user = new User();
        user.eat();  //eat
        user.eat("food");  //有参的eat
        user.setNo(100); //set为私有属性设置值
        System.out.println(user.getNo());  //get获得私有属性的值
    }
}

像这样要用一个类中的方法属性,就必须得先创建好一个类,然而有没有一种方法,能够在只知道一个类名的情况下,知道类的方法属性呢?

有,这就是今天讲的——反射

那为什么反射能够在只知道一个类名的情况下,就能知道到类的方法、属性?你得是有这个问题了

这是一个问题,我也不知道!!!!!看看底层代码吧,我也看不懂

我觉得这应该是底层实现的东西,目前我们需要知道的是:怎么使用反射,来帮助我们在只知道类名的情况下,调用类中的方法属性。

那我们目前见过的反射都有啥?

//java连接mysql数据库的时候JDBC中的注册驱动,当时说这个是反射
Class.forName("com.mysql.cj.jdbc.Driver"); 
//web.xml文件中配置servlet和filter的时候,当时说这也是用的反射
com.ffyc.webback.servlet.LoginServlet
com.ffyc.webback.filter.EncodingFilter

那反射到底是个啥?

反射是什么?

在运行状态中,对于任意一个类,都可以动态获取类的信息,可以调用对象中属性,方法.
这种动态获取,操作的方式称为反射机制.

我们需要了解,java反射相关的类里面有什么:

反射API:

Class 类型Constructor 构造方法 位于java.lang.reflect中Method 方法 位于java.lang.reflect中Field 属性 位于java.lang.reflect中

Class类型 ——> 反射机制基础,用反射机制,先获得类的Class对象

Constructor——>把构造方法也封装成了一个类,名字叫Constructor类

Method——>把类中的方法封装成一个类,就是Method类

Field——>把类中的属性封装成一个类,名字叫Field类

一个User类里面有的方法属性,反射中的类都有,只不过反射API将类的类型、方法、属性也都封装成了类而已。

下面分别介绍这四个反射中封装的类。

Class类

java反射机制的基础,用反射机制,先获得类的Class对象。通过Class类,可以得到一个类的信息。 获得类的Class对象

package com.ffyc.webback_final.reflect.demo1;

public class Test {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //User user = new User();

        
        User user = new User();
        System.out.println(user);  //com.ffyc.webback_final.reflect.demo1.User@7f31245a
        User user1 = new User();
        user.eat();  //eat
        user.eat("food");  //有参的eat
        user.setNo(100); //set为私有属性设置值
        System.out.println(user.getNo());  //get获得私有属性的值

        System.out.println("------------------------------------------------------");

        Class c1 =  user.getClass();
        Class c2 =  user1.getClass();
        System.out.println(c1);  //class com.ffyc.webback_final.reflect.demo1.User
        System.out.println(c1==c2);

         Class c3 =  User.class;
        System.out.println(c1==c3);

        String   classpath = "com.ffyc.webback_final.reflect.demo1.User";
        Class c4 =  Class.forName(classpath);
        System.out.println(c4);
        Object obj =  c4.newInstance();
        System.out.println(c4==c2);
    }
}
constructor类

getXXX()方法获得构造方法的基本信息

getName:返回构造方法的名字创建实例 :newInstance(Object…initargs)

Constructor类的实例通过Classs实例获得

package com.ffyc.webback_final.reflect.demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test2 {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
       Class c =  Class.forName("com.ffyc.webback.reflect.demo1.User");
       //Object user =  c.newInstance();

        
           

          Constructor[] cs =  c.getDeclaredConstructors();//获得到类中所有的构造方法.
    }
}
Field类

Field类属性封装,可以获得属性的值等信息,也可以对属性赋值。

getName:返回属性的名字Set:设置属性的值

获得Filed类的实例:通过Class类中的方法实现

package com.ffyc.webback_final.reflect.demo1;

import java.lang.reflect.Field;

public class Test3 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        Class c =  Class.forName("com.ffyc.webback_final.reflect.demo1.User");   //要用反射,先获得类的Class对象
        System.out.println(c);          //class com.ffyc.webback_final.reflect.demo1.User

        Object user = c.newInstance();
        System.out.println(user);       //com.ffyc.webback_final.reflect.demo1.User@7f31245a

        Field namef = c.getDeclaredField("no");
               namef.setAccessible(true);//允许访问操作私有成员
               namef.set(user,100);

        System.out.println(((User)user).getNo());

    }
}

Method类

Method类将类中的方法封装,可以动态获取方法的信息。

getName : 获取方法名字

getParameterType : 获得方法参数类型

除了动态获取方法信息,Method类还能动态调用某一个对象的具体方法;invoke 调用

invoke(Object obj,Object … args):使用obj调用改方法,参数为args

获得Method类的实例:通过Class类的方法获得

Method getMethod(String name,Class…parameterTypes):通过指定方法名,参数类型,返回一个Method实例

package com.ffyc.webback_final.reflect.demo1;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test4 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class c =  Class.forName("com.ffyc.webback.reflect.demo1.User");
        Object user = c.newInstance();

        //属性是私有的,不想直接对其操作,可以获得属性的公共的get,set方法
        //no
             String s = "name";
             Method m = c.getMethod("set"+String.valueOf(s.charAt(0)).toUpperCase()+s.substring(1),String.class);//setNo()
             m.invoke(user,"100");
             Method m1 = c.getMethod("get"+String.valueOf(s.charAt(0)).toUpperCase()+s.substring(1));//getNo()
             System.out.println(m1.invoke(user));

    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/749116.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号