美文网首页
反射泛型容器

反射泛型容器

作者: 顾子豪 | 来源:发表于2021-07-07 22:41 被阅读0次

一、 反射

1.1> 什么是反射

Class是反射的核心。在运行期进行实例的生成。

Class文件

  • 属性

  • 方法 (构造方法, 静态方法, 普通方法)

  • 包路径

  • 类名

    。。。。

1.2> 创建Class对象的种方式

三种方式

// 方式一  类.class
Class personClazz = Person.class;

// 方式二  实例.getClass()
Person person = new Person();
Class personClazz1 = person.getClass();

// 方式三  Class.forName("类的全路径")
Class personClazz2 = Class.forName("com.muse.Person");

1.3> 通过Class创建对象

  • 不去考虑反射,正常场景

    Person person = new person(); // 调用构造方法。

  • 考虑反射,同样也是需要靠构造方法来创建对象的。

    @Test
    public void test2() throws Throwable{
        // 第一步:获得Class
        Class personClazz = Person.class;

        // 第二步:获得构造方法
        // Constructor<Person> constructor = personClazz.getConstructor();
        // String name, Integer age, Byte sex, Boolean isMarriage
        Constructor<Person> constructor = personClazz.getConstructor(String.class, Integer.class, Byte.class,
                Boolean.class);

        // 第三步:创建对象 new Person(String name, Integer age, Byte sex, Boolean isMarriage)
        Person person = constructor.newInstance("muse", 10, (byte)1, true);

        // person.setName("muse");

        System.out.println(person);

    }

1.4> 通过反射获取属性值

反射是指将一个类的成员映射成相对应的java类型

成员:

  • 属性 Field.java
  • 方法 (构造方法 Constructor.java , 静态方法, 普通方法Method.java)
  • 包路径 Package.java
@Test
    public void test3() throws Throwable{
        // 第一步:获得Class
        Class personClazz = Person.class;

        // 第二步:获得构造方法
        Constructor<Person> constructor = personClazz.getConstructor();
        Person person = constructor.newInstance();

        // 第三步:通过Class对象,获得Field对象
        Field nameField = personClazz.getField("name");

        // 第四步:操作Field,获得属性值
        String name = String.valueOf(nameField.get(person));

        System.out.println(name);
    }

    /**
     * private
     *
     * @throws Throwable
     */
    @Test
    public void test4() throws Throwable{
        // 第一步:获得Class
        Class personClazz = Person.class;

        // 第二步:获得构造方法
        Constructor<Person> constructor = personClazz.getConstructor();
        Person person = constructor.newInstance();

        // 第三步:通过Class对象,获得Field对象
        Field sexField = personClazz.getDeclaredField("sex");
        sexField.setAccessible(true);

        // 第四步:操作Field,获得属性值
        System.out.println(sexField.get(person));
    }

1.5> 创建一个反射工具类

我们采用反射机制来实现一个工具BeanUtils,可以将一个对象属性相同的值赋值给另一个对象。

public class BeanUtils {

    public static void convertor(Object originObj, Object targetObj) throws Throwable{
        // 第一步,获得class对象
        Class orginClazz = originObj.getClass();
        Class targetClazz = targetObj.getClass();

        // 第二步,获得Field
        Field[] orginFields =  orginClazz.getDeclaredFields();
        Field[] targetFields =  targetClazz.getDeclaredFields();

        // 第三步:赋值呗
        for (Field originField : orginFields) {
            for (Field targetField : targetFields) {
                if (originField.getName().equals(targetField.getName())) {
                    originField.setAccessible(true);
                    targetField.setAccessible(true);
                    targetField.set(targetObj, originField.get(originObj));
                }
            }
        }
    }

    public static void main(String[] args) throws Throwable{
        // Service层返回的
        Person person = new Person("muse", 10, (byte)1, true);

        // 需要返回给前段实体对象
        Person1 person1 = new Person1();

        BeanUtils.convertor(person, person1);

        System.out.println("person, person1" + person + person1);
    }
}

二、泛型

2.1> 什么是泛型

Object 任意类型;String name = (String)xxxx; List<String> names = new ArrayList();

集合 Object Dog Cat

泛型:

产生优点:

1> 代码简洁。

2> 程序更加健壮。

3> 编码期,可读性很高了。

2.2> 泛型的基础

  • 类泛型

  • 方法泛型

  • 派生子类:

    1>子类明确类型

    2>子类不明确类型

  • 类型通配符 ?

public void test(List list) {
    for() {
        .....
    }
}

List<String> names = new ArrayList();
names.....值。
test(names); 不行的

public void test(List<Object> list) {
    for() {
        .....
    }
}

test(names); ok的
public void test(List<?> list) {
    for() {
        .....
    }
}

  • 通配符的上限 List< ? extends Number>
    /**
     * 去读,不去写
     */
    @Test
    public void tesePECSExtends() {
        List<Dog> dogs = Lists.newArrayList();
        dogs.add(new Dog());

        // 只知道animals里保存的是Animal的子类
        List<? extends Animal> animals = dogs;

        // animals.add(new Dog()); // 编译失败
        // animals.add(new Animal()); // 编译失败

        Animal animal = animals.get(0);
        // Dog dog = animals.get(0); // 编译失败

    }
  • 通配符的下限 List< ? super Type>

2.3> 类型擦除和桥接方法

// 最初的代码
public class Node<T> {
  public T data;
  
  public void setData(T data) {
     this.data = data;
  }
}

public class MyNode extends Node<Integer> {
  public void setData(Integer data) {
    ....
  }
}

// jvm不认识泛型的,把泛型擦除掉, 兼容老版本jdk
public class Node {
  public Object data;
  
  public void setData(Object data) {
     this.data = data;
  }
}

public class MyNode extends Node {
  
  // 桥接方法,编译器自动生成
  public void setData(Object data) {
     setData((Integer)data)
  }
  
  public void setData(Integer data) {
    ....
  }
}

三、 集合容器

3.1> List

  • ArrayList 源码解析
  • LinkedList源码解析

3.2> Map

  • HashMap 源码解析(jdk8 底层用的是数组+链表+红黑树)

    源码主要关注4大点:

    1> 确定哈希桶数组索引的位置

    HashMap.hash() ——> hashCode()

    2> 插入数据

    HashMap.put()

    3> 扩容机制

    resize()

    4> 红黑树

    treeify()

相关文章

  • 反射泛型容器

    一、 反射 1.1> 什么是反射 Class是反射的核心。在运行期进行实例的生成。 Class文件 属性 方法 (...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • Java 3 对象容器

    Ref:什么是泛型Java 容器 & 泛型(1):认识容器 3.1 顺序容器 我们首先学习的是顺序容器,即放进容器...

  • Java泛型

    本文介绍的知识点 泛型是什么? 泛型的使用在反射中使用泛型在集合类中使用泛型 关于泛型擦除如何理解?如何避免泛型擦...

  • 关于反射的使用

    反射中获取泛型参数信息

  • 【Java】【反射】泛型反射

    泛型反射 在运行时,泛型是无效的,所以可以通过反射在运行时将其他类型变量添加到集合,而不需要考虑泛型

  • 第十五章:泛型

    泛型实现了参数化类型的概念。 简单泛型 容器是出现泛型的重要原因之一。泛型的主要目的之一就是用来指定容器要持有什么...

  • Java自学-集合框架 泛型Generic

    ArrayList上使用泛型 步骤 1 : 泛型 Generic 不指定泛型的容器,可以存放任何类型的元素指定了泛...

  • Java笔记---泛型

    总结了泛型的基本语法、上下级通配符、泛型反射以及使用泛型的一些实践,看完还不会用泛型你顺着网线来打我(狗头)。 我...

  • 泛型、反射和注解

    泛型可以分为:泛型类,泛型接口和泛型方法 泛型类:容器类可以算的上是最具有重用性的类之一。 先来看一下一个没有泛型...

网友评论

      本文标题:反射泛型容器

      本文链接:https://www.haomeiwen.com/subject/tuafyltx.html