java之泛型

概述

泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化!

// 集合的声明 不使用泛型
List list = new ArrayList();
list.add("evan_qb");
list.add(1);
// 集合的使用 当不使用泛型时,会抛出运行时异常
String str = (String) list.get(1);
// 使用泛型
// 声明泛型集合的时候指定元素的类型  使用泛型后,当存储不同类型时,编译时期就会报错
List<String> list = new ArrayList<String>();
list.add("China");
//list.add(1);// 编译时期报错
String str = list.get(1); 

在运行时抛异常,和在编译时报错,显然,在编译时报错更容易定位错误

而且使用泛型也易于维护,不再鱼龙混杂,而是存储相同类型,易于维护,可以让你消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。

泛型擦除

泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!

泛型擦除实例

public void save(List<Person> p){
}
public void save(List<Dept> d){  // 报错: 与上面方法编译后一样
}

泛型写法

正确写法:

List<Object> list = new ArrayList<Object>();
List<String> list1 = new ArrayList<String>();
List list2 = new ArrayList<String>();

错误写法:

//泛型类型要一致
List<Object> list4 = new ArrayList<String>();
// 泛型类型必须是引用类型,不能为基本类型
List<int> list5 = new ArrayList<int>();

泛型方法/泛型类/泛型接口

泛型方法:

// 定义泛型方法
public <K,T> T save(T t,K k) { 
	return null;
}
// 使用泛型方法:  在使用泛型方法的时候,确定泛型类型
save(1.0f, 1);

泛型类:

public class GenericDemo<T> {
	// 定义泛型方法
	public <K> T save(T t,K k) {
		return null;
	}
}
// 泛型类:  在创建爱泛型类对象的时候,确定类型
GenericDemo<String> demo = new GenericDemo<String>();

泛型接口:

//定义泛型接口
public interface IBaseDao<T> {
	void save(T t );
	void update(T t );
}

泛型接口类型确定:

实现泛型接口的类也是抽象,那么类型在具体的实现中确定或创建泛型类的时候确定

public class BaseDao<T> implements IBaseDao<T> {}

在业务实现类中直接确定接口的类型

public class PersonDao implements IBaseDao<Person>{}

泛型关键字:

在泛型中:

?               指定只是接收值

extends      元素的类型必须继承自指定的类

super         元素的类型必须是指定的类的父类

关键字  ?
//只带泛型特征的方法
public void save(List<?> list) {
	// 只能获取、迭代list;  不能编辑list
}
// ?  可以接收任何泛型集合, 但是不能编辑集合值; 所以一般在方法参数中用
List<?> list = new ArrayList<String>();
//list.add("");// 报错
关键字:   extends【上限】

list集合只能处理 Double/Float/Integer等类型

限定元素范围:元素的类型要继承自Number类  (上限)

public void save(List<? extends Number> list) {
}
List<Double> list_1 = new ArrayList<Double>();
List<Float> list_2 = new ArrayList<Float>();
List<Integer> list_3 = new ArrayList<Integer>();
		
List<String> list_4 = new ArrayList<String>();	
// 调用
save(list_1);
save(list_2);
save(list_3);
save(list_4); //报错

关键字 :  super【下限】

super限定元素范围:必须是父类(Object)或者本身(String)【下限】

public void save(List<? super String> list) {
}
// 调用上面方法,必须传入String的父类
List<Object> list1 = new ArrayList<Object>();
List<String> list2 = new ArrayList<String>();
List<Integer> list3 = new ArrayList<Integer>();
save(list3);  //报错

泛型的反射

Type   接口,任何类型默认的接口!

包括: 引用类型、原始类型、参数化类型

List<String>  list  =  new   ArrayList<String>();

泛型集合:    list

集合元素定义:new   ArrayList<String>();  中的String

参数化类型:  ParameterizedType

即:“ArrayList<String>” 为参数化类型


泛型反射的案例:通用的jdbc方法

我们使用一个通用的BaseDao方法去存储基本的jdbc方法

由于本案例使用的数据库时Oracle数据库,还有DBUtil组件,所以需要导入相应的包


下面先写BaseDao类

public class BaseDao<T> {
	private Class clazz;
	private String tableName;
	/**
	 *  构造函数: 
	 *  1. 获取当前运行类的参数化类型; 
	 *  2. 获取参数化类型中实际类型的定义(class)
	 */
	public BaseDao(){
		//  this  表示当前运行类  (AccountDao/StudentDao)
		//  this.getClass()  当前运行类的字节码(AccountDao.class/StudentDao.class)
		//  this.getClass().getGenericSuperclass();  当前运行类的父类,即为BaseDao<Account>
		//   ParameterizedType,其实就是“参数化类型”
		//获取当前运行类的父类,Type类型表示任意类型
		Type type = this.getClass().getGenericSuperclass();
		//强制转换为ParameterizedType(参数化)类型
		ParameterizedType pt = (ParameterizedType) type;
		// 获取参数化类型中类似【new Type[]{Account.class}】,获取实际的参数类型
		Type[] types = pt.getActualTypeArguments();
		//获取数据的第一个元素:Account.class
		clazz = (Class) types[0];
		//获取表名
		tableName = clazz.getSimpleName();
	}
	public T findById(int id){
		Connection conn = null;
		String sql = "select * from " + tableName + " where id = ?";
		try {
			conn = ConnectionFactory.getConnection();
			System.out.println(tableName);
			QueryRunner qr = new QueryRunner();
			return qr.query(conn,sql, new BeanHandler<T>(clazz),id);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}finally{
			ConnectionFactory.close(conn, null, null, null);
		}
	}
	/**
	 * 获取所有
	 * @return
	 */
	public List<T> getAll(){
		Connection conn = null;
		String sql = "select * from " + tableName;
		try {
			conn = ConnectionFactory.getConnection();
			return new QueryRunner().query(conn, sql,new BeanListHandler<T>(clazz));
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}finally{
			ConnectionFactory.close(conn, null, null, null);
		}
	}
}

当谁需要用到这些方法时,我们就将其继承BaseDao,然后我们可以通过反射泛型的技术,或者正在运行的类的类型,然后进行相应的CRUD操作,而每个子类只需要定义特有的jdbc的方法就行了

分别编写Account类和Student类继承BaseDao类

public class AccountDao extends BaseDao<Account>{
}
public class StudentDao extends BaseDao<Student>{
}

Student实体类

public class Student {
	private int id;
	private String stuName;
	private double money;
	//省略getter和setter方法构造方法toString()方法
}

Account实体类

public class Account {
	private int id;
	private String accountName;
	private double money;
//省略getter和setter方法构造方法toString()方法
}

对应的创建表的语句:

create sequence account_seq increment by 1 start with 1;
create sequence stu_seq increment by 1 start with 1;
create table account(
       id number(10),
       accountName varchar2(20),
       money number(10,2)
);
create table Student(
       id number(10),
       stuName varchar2(20),
       money number(10,2)
);

drop table student;

-- 插入数据到account表中
insert into account values(account_seq.nextval,'张三',1000.00);
insert into account values(account_seq.nextval,'李四',2000.00);

--插入数据到Student表中
insert into student values(stu_seq.nextval,'evan_qb',500.00);
insert into student values(stu_seq.nextval,'李四',1000.00);
commit

然后我们就来测试一波

StudentDao stuDao = new StudentDao();
List<Student> stus = stuDao.getAll();
for (Student stu : stus) {
System.out.println(stu);

运行结果如下:



AccountDao account = new AccountDao();
Account account1 = account.findById(1);
//List<Account> accounts = account.getAll();
System.out.println(account1);

运行结果如下:


这样,我们就用反射泛型实现了对jdbc的优化




资源下载链接为: https://pan.quark.cn/s/67c535f75d4c 在机器人技术中,轨迹规划是实现机器人从一个位置平稳高效移动到另一个位置的核心环节。本资源提供了一套基于 MATLAB 的机器人轨迹规划程序,涵盖了关节空间和笛卡尔空间两种规划方式。MATLAB 是一种强大的数值计算与可视化工具,凭借其灵活易用的特点,常被用于机器人控制算法的开发与仿真。 关节空间轨迹规划主要关注机器人各关节角度的变化,生成从初始配置到目标配置的连续路径。其关键知识点包括: 关节变量:指机器人各关节的旋转角度或伸缩长度。 运动学逆解:通过数学方法从末端执行器的目标位置反推关节变量。 路径平滑:确保关节变量轨迹连续且无抖动,常用方法有 S 曲线拟合、多项式插值等。 速度和加速度限制:考虑关节的实际物理限制,确保轨迹在允许的动态范围内。 碰撞避免:在规划过程中避免关节与其他物体发生碰撞。 笛卡尔空间轨迹规划直接处理机器人末端执行器在工作空间中的位置和姿态变化,涉及以下内容: 工作空间:机器人可到达的所有三维空间点的集合。 路径规划:在工作空间中找到一条从起点到终点的无碰撞路径。 障碍物表示:采用二维或三维网格、Voronoi 图、Octree 等数据结构表示工作空间中的障碍物。 轨迹生成:通过样条曲线、直线插值等方法生成平滑路径。 实时更新:在规划过程中实时检测并避开新出现的障碍物。 在 MATLAB 中实现上述规划方法,可以借助其内置函数和工具箱: 优化工具箱:用于解决运动学逆解和路径规划中的优化问题。 Simulink:可视化建模环境,适合构建和仿真复杂的控制系统。 ODE 求解器:如 ode45,用于求解机器人动力学方程和轨迹执行过程中的运动学问题。 在实际应用中,通常会结合关节空间和笛卡尔空间的规划方法。先在关节空间生成平滑轨迹,再通过运动学正解将关节轨迹转换为笛卡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值