Java泛型和反射

一、泛型

1、泛型的本质是为了参数化类型

2、泛型的优点:

  • 类型安全:比如往集合list里add不符合参数类型的值时会报错;

  • 消除强制转换:在非泛型编程中,将简单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作

3、泛型的使用:

        泛型类:泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口(模板模式)

//格式
public class 类名 <泛型类型1,...> {
    
}

        泛型方法:在调用方法的时候指明泛型的具体类型

//格式
public <泛型类型> 返回类型 方法名(泛型类型 变量名) {
    
}

        泛型类接口:类似泛型类

4、泛型通配符:

E: Element (在集合中使用,因为集合中存放的是元素)

T:Type(Java 类)

K: Key(键)

V: Value(值)

N: Number(数值类型)

?: 表示不确定的java类型

  • 通配符上界:<? extends T>

        在类型参数中使用 extends 表示这个泛型中的参数必须是 E 或者 E 的子类。使用固定上边界的通配符的泛型, 就能够接受指定类及其子类类型的数据。要声明使用该类通配符, 采用<? extends E>的形式, 这里的E就是该泛型的上边界。

  • 通配符下界:<? super T>

        在类型参数中使用 super 表示这个泛型中的参数必须是 E 或者 E 的父类。

  • 无界通配符:<?>,即类型参数可以是任何类型

5、类型擦除:

        指在编译期间,所有的泛型信息都会被擦除掉,我们常称为泛型擦除。

@Test
public void test() {
    List<String> stringList = new ArrayList<String>();
    stringList.add("泛型");
    List<Integer> integerList = new ArrayList<Integer>();
    integerList.add(1);
    System.out.println(stringList.getClass() == integerList.getClass());
}

//结果
true

        其中定义了两个List,不过一个是List泛型类型,只能存储字符串。一个是List泛型类型,只能存储整型。最后,我们通过stringList对象和integerList对象的getClass方法获取它们的类的信息,最后发现结果为true。说明泛型类型String和Integer都被擦除掉了,只剩下了原始类型。

二、反射

1、概述:

        JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

        要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

        反射就是把Java的各种成分映射成相应的Java类,通过Class对象,我们可以去找到各种成分对应的Java类,从而在运行状态中就可以找到目标成分。

  • Class类:代表一个类
  • Field类:代表类的成员变量(类的属性)
  • Method类:代表类的方法
  • Constructor类:代表类的构造方法
  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法

2、Class类:

        Class类的格式如下:

public final class Class<T> extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement

        Class类没有公共构造方法,Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。

3、获取Class对象的三种方式:

  • Object.getClass();

  • 任何数据类型(包括基本数据类型)都有一个“静态”的class属性

  • 通过Class类的静态方法:forName(String className)(常用)

package fanshe;
/**
 * 获取Class对象的三种方式
 * 1 Object ——> getClass();
 * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
 * 3 通过Class类的静态方法:forName(String  className)(常用)
 *
 */
public class Fanshe {
        public static void main(String[] args) {
                //第一种方式获取Class对象  
                Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
                Class stuClass = stu1.getClass();//获取Class对象
                System.out.println(stuClass.getName());
                
                //第二种方式获取Class对象
                Class stuClass2 = Student.class;
                System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
                
                //第三种方式获取Class对象
                try {
                        Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
                        System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
                } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                }
                
        }
}

4、API调用反射

4.1 利用反射实例化对象:

实体类:

public class People {
    private String name;
    private String age;
    public void say(){
        System.out.println("my name is "+name+"\t"+age+" years old");
    }
}

实例化:

try {
            //方式1
            People people = (People) Class.forName("com.eryi.People").newInstance();
            //方式2
//           Constructor<People> constructor=People.class.getConstructor();
//            People people= constructor.newInstance();
            people.say();
        } catch (Exception e) {
            e.printStackTrace();
        }

 

所以Java中共有四种方法实例化对象:

  • new

  • clone

  • 序列化

  • 反射

4.2 获取方法

        JAVA提供Method类型来表示方法,Class类中方法相关的API如下:

API功能

classType.getMethods()

获取当前类以及父类的public方法

classType.getDeclareMethods()

获取当前类的所有方法

classType. getMethod(String name.Class<?>... parameterTypes)

获得当前类以及父类指定的public方法

classType. getDeclaredMethod(String name,Class<?>... parameterTypes)

获得当前类的指定的Method

示例:

 
//获取类对象
                Class<?> classType=Class.forName("reflection.emplee");
                
                //调带参构造实例化
                Constructor<?> constructor2=classType.getConstructor(new Class[]{String.class,int.class});
                emplee e3=(emplee)constructor2.newInstance(new Object[]{"张三",30});
                
                //获得指定方法
                Method method1=classType.getDeclaredMethod("toString",new Class[]{});
                String result1=(String)method1.invoke(e3, new Object[]{});
                System.out.println(result1);
                
                //获得全部方法(包括私有)
                Method[] methods=classType.getDeclaredMethods();
                for (Method m : methods) {
                        System.out.println("方法名:"+m.getName()+"\t"+"返回值类型:"+m.getReturnType());
                }
                
                //调用私有方法
                Method method2=classType.getDeclaredMethod("getName",new Class[]{});
                //关闭安全检查
                method2.setAccessible(true);
                String result2=(String)method2.invoke(e3, new Object[]{});
                System.out.println(result2);

4.3 获取属性

        JAVA提供Method类型来表示属性,Class类中与属性相关的API如下:

API功能

classType. getFields()

获得当前类以及超类的public Field

classType. getDeclaredFields()

获得当前类申明的所有Field

classType. getField(String name)

获得当前类以及超类指定的public Field

classType. getDeclaredField(String name)

获得当前类申明的指定的Field

field.set(Object obj, Object value)

通过反射动态设定Field的值

Object obj = field.get(Object obj)

通过反射动态获取Field的值

示例:

//获取class对象所指定的属性,包括私有的
Field field = classType.getDeclaredField("name");
//关闭安全检查
field.setAccessible(true);"李四") ;
field.set(employeeSystem.out.println(field.get (employee)) ;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值