二十八、泛型和反射

一、泛型

原因:

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

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

简述:

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

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

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

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

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

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

//通过泛型实现
public class FanXing1 {
	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  t1=new Test1(); //正确的

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

Test1  t1=new Test1(); //错误

Test1  t1=new Test1();//正确

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

错误示范:

FanXing1 n2 = new FanXing1();

n2.setA(18);

int a = n2.getA();

n2.setB("小明");

String b = n2.getB();

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

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

java.util Class ArrayList

java.util Class HashMap

java.util Class Hashtable

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

java.util Interface Map

public interface List

public interface Collection

二、反射

1概念

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

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

2反射的使用场景:

1、jdbc加载数据库驱动

2、Servlet的web.xml配置

3、Spring框架

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

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

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

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

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

class:创建类的关键字

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

public final class Class

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

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

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

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

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

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

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

返回值类型

方法体

作用

Constructor[]

getConstructors()

得到构造方法

Field[]

getDeclaredFields()

得到成员变量

Method[]

getDeclaredMethods()

得到成员方法

Class[]

getInterfaces()

得到接口

Class

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);
	}
}

结果图

二十八、泛型和反射_第1张图片

 无奈源于不够强大

你可能感兴趣的:(JavaSE,java,开发语言,后端)