二十八、泛型和反射

本文详细介绍了Java中的泛型和反射机制。首先解释了泛型的引入原因,即解决类型安全问题,并展示了如何创建和使用泛型类、接口。接着,详细阐述了反射的概念,说明其在JDBC、Servlet和Spring框架中的应用。还提供了通过反射获取类的构造方法、成员变量、成员方法等信息的方法,并给出了实例代码。最后,通过一个具体的示例展示了如何利用反射打印类的完整结构。
摘要由CSDN通过智能技术生成

一、泛型

原因:

广泛的数据类型,本质上定义安全的类型。在没有出现泛型前,Java提供了对Object的引用“任意化”操作,这种任意化的操作就对Object引用进行向下转型及向上转型的类型操作,但某些强制类型转换的错误也许不会被编译器捕获,而在运行后出现异常,可以强制类型转换存在安全隐患,所以提供了泛型机制。

如果转换不当会出现类型转换异常java.lang.ClassCastException。

简述:

将某一个类/接口/方法/变量的数据类型象使用参数一样传递给类/接口/方法/变量。

数据类型的参数化,任意化。

1.如何创建一个泛型类/泛型接口?

在创建类的时候为类名后面添加一个“<>”,给”<>”中添加单个的大写字母,用来接收具体的某个数据类型。

”<>”中的单个的大写字母可以出现多个,中间使用”,”分割。

类中需要数据类型的部分可以使用单个的大写字母来代替,这是我们我们创建类的时候就可以传递具体的数据类型给单个的大写字母,类中需要数据类型的部分全部都会变成我们传递具体的数据类型。

//通过泛型实现
public class FanXing1<T,I> {
	private T A;
	private I B;
	public T getA() {

		return A;
	}
	public void setA(T a) {
		A = a;
	}
	public I getB() {
		return B;
	}
	public void setB(I b) {
		B = b;
	}
	
}

2.泛型类/泛型接口如何使用?

我们一般很少创建与泛型有关的元素,我们会经常使用jdk提供的开发包中的泛型类/接口。

(1)使用泛型类创建对象的时候需要传递具体的数据类型。

Test1  t1=new Test1(); //不合法的,会产生警告信息

Test1<Integer,String>  t1=new Test1<Integer,String>(); //正确的

(2)基本数据类型在被作为泛型的数据类型时,是不被允许的,可以使用应基本类型对应的封装类型代替

Test1<int,String>  t1=new Test1<int,String>(); //错误

Test1<Integer,String>  t1=new Test1<Integer,String>();//正确

(3).当我们创建泛型对象的时候,没有传递指定的数据类型默认是Object类型。并伴随有警告信息出现。

错误示范:

FanXing1<Integer, String> n2 = new FanXing1<Integer,String>();

n2.setA(18);

int a = n2.getA();

n2.setB("小明");

String b = n2.getB();

System.out.println(a  + "== " + b);

之前学习过的类,他们其实是泛型类

java.util Class ArrayList<E>

java.util Class HashMap<K,V>

java.util Class Hashtable<K,V>

之前学习过的接口,他其实是泛型接口

java.util Interface Map<K,V>

public interface List<E>

public interface Collection<E>

二、反射

1概念

反射:在程序运行的过程中,我们可以得到某个类的对象,可以调用某个类中的任何一个变量/方法,这种动态获取信息的过程就是反射。

当我们在没有见过某个类的情况下,仅凭一个完整的类名【包名+类名】,就可以获取到整个类的所有信息。

2反射的使用场景:

1、jdbc加载数据库驱动

2、Servlet的web.xml配置

3、Spring框架

3、实例对象与反射对象的相互转换?

实例对象:就是我们通过类创建的对象

反射对象:通过反射机制得到的类对象

例如:  反射就是一面镜子,镜子前面的你就是实例对象,通过镜子得到的镜子里面的你就是反射对象。

反射对象是一个Class类型的对象

class:创建类的关键字

Class:类的类名,创建出来的Class类的对象就是反射对象。

public final class Class<T>

(1)通过实例对象得到反射对象

  • 通过实例对象的getClass()得到,当前实例对象对应的反射对象
  • 通过Class类的forname(类名【包名+类名】)

(2)通过反射对象得到实例对象

反射对象的newInstance()方法,可以得到实例对象

目前得到一个类的实例对象的方式:

1.new     2.静态方法      3.反射

4、通过反射对象得到类的完整结构

返回值类型

方法体

作用

Constructor<?>[]

getConstructors()

得到构造方法

Field[]

getDeclaredFields()

得到成员变量

Method[]

getDeclaredMethods()

得到成员方法

Class<?>[]

getInterfaces()

得到接口

Class<? super T>

getSuperclass()

得到父类

Package

getPackage()

得到包对象

int

getModifiers()

Java语言修饰符

Modifier

toString(int mod)

得到int对应的修饰符

String

getName()

得到类名称

例子:打印一个类

需要打印的类

package com20211204;

public class ConsoleTest extends Student implements Teacher,Stfn{
	public String msg;
	public int stuid; 
	public ConsoleTest(int id,String msg) {
		this.stuid = id;
		this.msg = msg;
	}
	@Override
	public void sum() {
		//入学考试
		System.out.println(15);
	}
	public String getMsg() throws Exception{
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public int getStuid() {
		return stuid;
	}

	public void setStuid(int stuid) {
		this.stuid = stuid;
	}

	public String fn(){
		return "睡觉";
	}
}

通过泛型对象的方法打印上述的代码

提供包名和类名

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import java.lang.reflect.Parameter;

public class Classexmple {
	// com20211204.ConsoleTest
	// 得到这个类的结构
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> fn = Class.forName("com20211204.ConsoleTest");
		// 输出第一行
		String packename = fn.getPackage().getName();
		System.out.println(packename);
		// 输出第二行
		StringBuilder towline = new StringBuilder();
		int g = fn.getModifiers();
		String modidfyname = Modifier.toString(g);
		towline.append(modidfyname);
		// 输出类头
		String clasname = substr(fn.getName());
		towline.append(" " + clasname);
		// 获取继承父类
		Class<?> superClass = fn.getSuperclass();
		String supername = substr(superClass.getName());
		towline.append(" extends " + supername);
		// 获取实现的接口
		towline.append(" implements ");
		Class<?>[] impClass = fn.getInterfaces();
		for (Class<?> class1 : impClass) {
			String intername = substr(class1.getName());
			towline.append(intername + ",");
		}
		towline.replace(towline.lastIndexOf(","), towline.length(), " {");
		System.out.println(towline);
		// 输出成员变量
		Field fields[] = fn.getFields();
		for (Field field : fields) {
			String str = "\t";
			g = field.getModifiers();
			str += Modifier.toString(g) + " ";
			str += substr(field.getType().getName()) + " ";
			str += field.getName() + ";";
			System.out.println(str);
		}
		// 获取构造方法
		StringBuilder constr = new StringBuilder();
		Constructor<?> constrol = fn.getConstructors()[0];
		String modystr = Modifier.toString(constrol.getModifiers());
		constr.append("\t" + modystr);
		String conName = substr(constrol.getName());
		constr.append(" " + conName + "(");
		Parameter[] parameters = constrol.getParameters();
		for (Parameter parameter : parameters) {
			Class<?> parametertype = parameter.getType();
			String modif = substr(parametertype.getName());
			String paramstr = substr(parameter.getName());
			constr.append(modif + " " + paramstr + ", ");
		}
		constr.replace(constr.lastIndexOf(","), constr.length(), "){");
		System.out.println(constr);
		System.out.println("\t\tthis.stuid = id;\n" + "\t\tthis.msg = msg;");
		System.out.println("\t}");
		// 获取实例方法
		Method methods[] = fn.getDeclaredMethods();
		
		for (Method method : methods) {
			int f=  method.getModifiers();
			String str ="\t" + Modifier.toString(f) + " ";
			Class<?> n =  method.getReturnType();
			str += substr(n.getName());
			str += (" " + method.getName() + "(");
			Parameter pms[] = method.getParameters();
			for (Parameter pm: pms) {
				f=  method.getModifiers();
				String b =Modifier.toString(f) + " ";
				str+=(b+" " +pm.getName() + ",");
			}
			if (str.indexOf(",") != -1) {
				str =	str.substring(0, str.lastIndexOf(",") -1);
			}
			str+="){}";
			System.out.println(str);
		}
		
	}
	static String substr(String str) {
		return str.substring(str.lastIndexOf(".") + 1);
	}
}

结果图

 无奈源于不够强大

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值