资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

反射知识小结-创新互联

目录

创新互联公司是一家集网站建设,日土企业网站建设,日土品牌网站建设,网站定制,日土网站建设报价,网络营销,网络优化,日土网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

1.引出反射(案例回顾)

2.为什么用反射机制?

3.什么是反射机制?

4.Java反射Api的演示

4.1获取类的Class对象

4.2construct(构造方法)

 4.3Field和Method(属性和方法)

5.案例

6.反射的优点和缺点


1.引出反射(案例回顾)

  记得之前我们所学过的配置servlet-class时:

dormclerkServlet

com.ffyc.dormms.servlet.DormClerkServlet

  还有像mybatis sql映射文件当中:

resultType="com.ffyc.mybatispro.model.Admin">  配置了哪个类,框架就创建出该类的对象

  还有我们最为熟悉的mysql驱动:

Class.forName("com.mysql.cj.jdbc.Driver");       配置类地址,加载类 

总结:像这些我们给出一个类地址,就可以通过反射机制,实现动态类的获取与创建对象功能。

2.为什么用反射机制?

以前我们会先定义一个类,类里定义所需属性和方法后,然后再导包,之后new对象,这种在业务逻辑层是完全没问题的,只不过稍显死板。那么我们可以定义一套机制,来处理任意的类,以不变应万变,就可以使程序更加的灵活。

3.什么是反射机制?

Java的反射机制是指在程序运行时侯,我们可以动态的获取到类中的属性和方法,对于任意一个对象可以动态的调用对象中的属性以及方法,像这种可以动态的获取类中信息或对象信息的功能我们称之为反射机制。

4.Java反射Api的演示

java.lang.Class     表示一个正在运行中的类或接口
 java.lang.reflect.Constructor
 java.lang.reflect.Method
 java.lang.reflect.Field

首先我们创建一个Admin类:

public class Admin {
    private int id;
    private String account;
    private String password;
    
    public Admin() {
    }

    private Admin(int id, String account, String password) {
        this.id = id;
        this.account = account;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
4.1获取类的Class对象

一旦一个类被加载进内存,就会为该类创建Class类的对象(Class),可以通过该对象来获取类中的信息。如果要用反射机制来操作,第一步就是先获取到该类的Class类的对象。

Class.forName("类地址")多用于配置文件
new User().getClass()多用于对象获取Class对象
User.class多用于参数传递

  利用Class类的对象来创建类的对象:

Classc1 = Class.forName("model.Admin");

  Object obj   = c1.newInstance();  //由于我们没定义类通配符类型,所以创建的对象为Object类型。

注意:无论哪种方式获取类的Class对象,都是一样的,因为一个类只有一个Class对象。

4.2construct(构造方法)
getConstruct()获取公共无参构造方法
getConstruct(Class... parameterTypes)获取公共的带参构造方法(参数为参数类型.class)
getDeclaredConstruct( Class... parameterTypes)获取带参构造方法(包括私有的)
getDeclaredConstructs()获取所有构造方法(包括私有的)

//获取类中的公共无参构造方法

Constructorconstructor = c1.getConstructor();

//利用无参构造方法创建对象

Object obj2 = constructor.newInstance();

注意:如果我们获取到的是私有的构造方法,我们只能查看其参数类型,而不能使用其功能。但是我们既然能够拿到这个私有构造方法,我们甚至可以修改其可见性!!!   

Constructorconstruct = c1.getDeclaredConstructor(int.class, String.class,String.class);
System.out.println(Arrays.toString(construct.getParameters()));//可以查看参数类型
construct.setAccessible(true); //设置可访问 打破封装性
Object obj = construct.newInstance(1, "Tom","123"); //利用构造创建对象
System.out.println(obj);
 4.3Field和Method(属性和方法)
Classc1 = Class.forName("model.Admin");
Object obj = c1.newInstance();
//获取对应属性(包括私有)
Field field = c1.getDeclaredField("id");
//获取到所有属性(包括私有)
Field[] fields = c1.getDeclaredFields();
//获取属性的名字
String property = field.getName()
//获取属性的类型(会解析)
Classc = field.getType()
//给对象的属性赋值,如果属性私有,需要设置可见性
field.set(Object obj, Object value)
//获取对象中对应字段的值,如果属性私有,需要设置可见性
field.get(Object obj)

相应的我们不建议使用field中的方法直接对数据进行操作,因为对传来的数据安全性未判断,而且我们的类中提供了相应get和set方法,那么我们怎么使用get和set方法呢?这就照应了我们定义get,set方法名时的规律了,细看就会发现我们在起get和set方法名时,是有一定的规律的(get/set+属性名第一个字符大写+后面字符)

可以通过方法名和参数(可能有重载)拿到方法。
getMethod(@NonNls @NotNull String name,Class... parameterTypes)
//拿到方法
Method method = c1.getMethod("set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1), field.getType());
//调用方法
method.invoke(Object obj,Object... args);
5.案例

  要求:将任意对象转换为类似json字符串格式。

public class Demo {
    public static String ObjToJson(Object obj) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        StringBuilder sb = new StringBuilder("{");
        Class c1 = obj.getClass();
        Field[] fields = c1.getDeclaredFields();
        for (Field field : fields) {
            String property = field.getName();//获取到属性值
            sb.append(property+":");
            Method method = c1.getMethod("get" + property.substring(0, 1).toUpperCase() + property.substring(1));//拿到获取属性值的方法
            Object value = method.invoke(obj);//调用get方法,获取到值
            if(field.getType()==String.class){
                sb.append("'"+value+"'"+",");  //如果是字符串则需要加''
            }else {
                sb.append(value + ",");
            }
        }
        String s =sb.substring(0,sb.length()-1);//将最后多余的,去掉
        return  s+="}";
    }
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Admin admin = new Admin();
        admin.setId(1);
        admin.setAccount("zhangsan");
        admin.setPassword("123");
        String json = ObjToJson(admin);
        System.out.println(json);//{id:1,account:'zhangsan',password:'123'}
    }
}
6.反射的优点和缺点

优点:

1.增加程序的灵活性,可以在运行时动态操作类。

2.提高复用率,动态代理。

3.可以轻松获取一个类中的属性和方法,也可以动态调用。 

缺点:

1.不安全,可以调用私有类成员,并设置可访问权限,打破了封装性。 

2.反射会涉及到对类型的解析,导致性能低。

3.使用反射技术通常要在一个没有安全限制的程序运行。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


标题名称:反射知识小结-创新互联
URL地址:http://cdkjz.cn/article/cegdgh.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220