【笔记】JAVA中的泛型和反射

泛型

Java的泛型是如何工作的?什么是类型擦除?
----泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。例如List在运行时仅用一个List来表示。这样做的目的是确保能和Java 5之前的版本开发二进制类库兼容。无法在运行时访问到类型参
数,因为编译器已经把泛型类型转换成了原始类型。
**泛型提供了编译期的类型安全,确保只能把正确类型的对象放入集合中,**避免了在运行时出现ClassCastException。

利用泛型方法,还可以定义具有可变参数的方法,如printf()方法,具体格式如下:
System.out.printf("%d,%f\n",i,f);
System.out.printf(“x=%d,y=%d,z=%d”,x,y,z);
定义时“类型参数名”后面一定要加上“…”,表示是可变参数。“参数名”实际上是一个数组,当具有可变参数的方法被调用时,是将实际参数放到各个数组元素中。

public class test{
static <T> void print(T..ts)
{
//泛型方法,形参是可变参数
for(int i = 0;i < ts.length;i++)
{
System.out.PrintIn(ts[i]+" ");
}
}
public static void main(String args[]){
String fruit[] = ["apple","pear","peach"];
print(fruit);
}

}

泛型接口:

interface test<T>
{
public T next();
}

在Java中,泛型增加了许多新的特性,其中最主要的有两个:使用“::”对方法和构造方法进行引用,以及Lambda表达式的作用域。
方法与构造方法引用
Java中可以使用“::”传递方法或构造函数引用。

//创建接口。
public interface 
InterNew<String, Integer> {
Integer InterNew(String string);}
//创建引用静态方法的类。
public class FuncNew {
public static void main(String[] args){
//引用静态方法valueOf()
InterNew<String, Integer> in2 = Integer::valueOf;
//使用valueOf()方法将字符串转换为Integer类型
Integer i2 = in2.InterNew("25");
System.out.println("方法引用-String -> Integer:" + i2);
}
}

反射

在程序运行过程中,对于任意一个对象,都能够知道这个对象所在类的所有属性和方法,都能够调用它的任意一个方法和访问它的任意一个属性,这种动态调用对象的方法及动态获取信息的功能称为Java语言的反射机制。
通过Java的反射机制,程序员可以方便、灵活地创建代码,这些代码可以在运行时进行装配,在程序运行过程中可以动态地扩展程序。
Java的反射机制主要有以下功能:
·在运行时判断任意一个对象所属的类。
·在运行时构造任意一个类的对象。
·在运行时判断任意一个类所具有的成员变量和方法。
·在运行时调用任意一个对象的方法。
·生成动态代理。
Java提供的反射所需要的类主要有java.lang.Class类和java.lang.reflect包中的Field类、Constructor类、Method类和Array类等。
·Class类的实例表示正在运行的Java应用程序中的类和接口。它是Java反射的基础,对于任何一个类,首先要产生一个Class的对象,然后才可以通过Class类获得其他的信息。
·Field类提供有关类或接口的单个字段的信息以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。该类封装了反射类的属性。
·Constructor类提供关于类的单个构造方法的信息以及对它的访问权限。该类封装了反射类的构造方法。
·Method类提供关于类或接口上单独某个方法的信息,该方法可能是类方法或实例方法(包括抽象方法)。该类是用来封装反射类的方法。
·Array类提供了动态创建和访问Java数组的方法。它提供的方法都是静态方法。

Class类
Java程序运行时,系统对所有对象赋予运行时类型标识,Class类是用来保存类型信息的类。Java虚拟机为每种类型管理着一个独一无二的Class类。即Java虚拟机中会有一个Class对象,保存运行时的类和接口的类型信息。

获取Class类对象

在Java语言中,获取Class类对象的方式有3种,具体如下。
(1)通过Object类提供的getClass()方法获得Class类对象。这是获取Class类对象最常见的一种方式,具体格式如下:
Object obj = new Object(); //创建Object类对象
Class c1 = obj.getClass(); //调用Object类的getClass()方法获取Class
(2)通过Class类的静态方法forName()获取字符串参数指定的Class类对象。具体格式如下:
Class c2 = Class.forName(“java.lang.Integer”);
(3)通过“类名.class”获取该类的Class对象。具体格式如下:
Class c3= Integer.class;

c3:通过“类名.class”获取的Class类对象。

生成对象

在Java程序中,通常使用new关键字调用类的构造方法来创建对象。但是,对于一些特殊情况,例如程序只有在运行时才知道要创建对象的类名,就需要使用Java的反射机制来创建对象。使用Java的反射机制创建对象有两种方法,即无参构造方法和有参构造方法。
 无参构造方法
若使用无参数的构造方法创建对象,首先要获得这个类的Class类对象,然后调用Class类对象的newInstance()方法。具体代码如下:

Class c2 = Class.forName("java.lang.Integer"); //获得Class类对象
c2.newInstance();

有参构造方法
若使用带参数的构造方法创建对象的具体步骤如下:
(1)获得指定类的Class类对象。
(2)通过反射获取符合指定参数类型的构造方法类(Constructor类)对象。
(3)调用Constructor类对象的newInstance()方法传入对应参数值,创建对象。

import java.lang.reflect.*;
public class ClassObj {
public static void main(String[] args){
//使用有参构造方法创建对象
try {
//第一步,获得指定类的Class类对象
Class c5 = Class.forName("java.lang.Integer");
//第二步,通过Class类对象获得指定符合参数类型的构造方法
Constructor construct = c5.getConstructor(int.class);
//第三步,通过Constructor类对象的newInstance()方法传入参数,创建
Integer in = (Integer) construct.newInstance(1246);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值