泛型
是一种安全机制。
表明
参数或者
接口或者
类的数据类型
泛型在什么时候使用?
当不确定某个参数的类型的时候可用泛型。
泛型的类
1、泛型类在多个方法前面间实施类型约束。
2、
泛型一旦作用于类,那么该类的所有函数都可以使用该泛型类
3、实例化该类的时候需要加入泛型确保安全。
泛型的函数
1、通常情况下参数内部不知道类型的时候使用泛型。
public <QQ> void run(QQ q)
静态泛型函数:
1、静态函数不可以访问类上定义的泛型。
2、如果静态方法操作的应用数据类型不确定,
那么在函数上确定好泛型
泛型接口:
interface
Run<TT>{
public void run(TT a);
public void runrun(TT b);
}
class RunImpl implements
Run<String>{
public void run(String a){
}
public void runrun(String b){
}
}
需要注意的是:一旦使用名字,那么在实现的时候
需要确定是何种类型。
谁用了迭代器,迭代器的泛型就要与谁的泛型相同
命名空间:相当于某个文件的路径
字节流:计算机最底层,最基础的
泛型通配符
来自官方普通的四种泛型
<K> 键 <V> 值 <E> 异常类 <T> 普通泛型
特殊情况:
1、泛型的参数如果不考虑继承的话,
会报错的,除非用?
泛型通配符有三种:
1、
无限定通配符 , <?>
2、
上边界限定通配符 ,<? extends Number>
ArrayList<? extends 类型1> x = new ArrayList<类型2>();
类型1指定了一个数据类型,
那么类型2只能是类型1或者类型1的子类
3、
下边界限定通配符 ,<? super Number>
ArrayList<? super 类型1> x = new ArrayList<类型2>();
类型1指定了一个数据类型,
那么类型2就只能是类型1或者类型1的父类
限定通配符总是包括自己!
例:
import java.util.*;
public class GernerictiyRepeat01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//1、普通的泛型表示方式
// 这个时候我需要表明我需要的是哪种类型,因此需要加入泛型。
// 因为在数组里其实是有规定加入的哪种数据类型,而集合里没有。
ArrayList<String> list1 = new ArrayList<String>();
list1.add( "1234" );
list1.add( "3456" );
//list1.add( 1 );//一旦定义了泛型,那么此句是错误的。
Human<Integer> human = new Human<Integer>( new Integer(1) );
//6、泛型通配符
/*
* 在通常的情况下,
泛型中如果你不确定2种事物之间是否有联系,
* 那么就用?作为类型表示
*
* */
ArrayList<String> array = new ArrayList<String>();
new GernerictiyRepeat01().run( array );
//7、泛型限定符
ArrayList<
Mother> list3= new ArrayList<Mother>();
list3.add( new Mother() );
new GernerictiyRepeat01().sing( list3 );
ArrayList<
Man> list4 = new ArrayList<Man>();
list4.add( new Man() );
new GernerictiyRepeat01().sing( list4 );
}
//7、向上限定 方式(高级应用)。
/*
*
向上限定,表示的是事物之间的一种联系。
* 如果用了向上限定,表示上限为类型1
* 那么就是类型1就是类型2的父类。
*
* ArrayList1<类型1> array1 = new ArrayList<类型2>();
*
* 此处方法,泛型决定上限是Mother,也就是说你可以传Mother 或者 Man
*
* 注意:
<? extends Mother> 可以接受本类和子类,但是无法添加任何元素。
*
因为它根本不知道你本类还是子类,因为这对泛型来说是违背的,因为泛型本身就需要确定某一种数据类型。
* 因此如果需要添加,只能添加null.
* 但是
一般<? extends Mother>可以用来获取元素
*/
public void sing(Collection<? extends Mother> col ){
ArrayList<? extends Mother> mother = new ArrayList<Man>();
//mother.add( new Mother() );//此处由于上限定是父类所以不清楚加入的类型,因此在此处不允许
//mother.add( new Man() );
//8、向下限定 方式(高级应用)。
/*
* 向下限定,表示的是事物之间的一种联系。
* 如果用了向下限定,表示下限为类型1
* 那么就是类型1就是类型2的子类或者本类。
*
* ArrayList1<类型1> array1 = new ArrayList<类型2>();
*
* 此处方法,泛型决定下限是Man,也就是说你可以传Mother 或者 Man
*
* 注意:<? super Mother/Man> 可以接受本类和子类,但是无法获取元素。
*
* 工业上,不常用。
*/
ArrayList<? super Mother> man = new ArrayList<Mother>();
/*ArrayList<? super Mother> man1 = new ArrayList<Mother>();
man.add( new Man() );
man1.add( new Mother() );
man1.add( new Man() );*/
//error ? 值 ? null
for( Iterator<? extends Mother> itr = col.iterator(); itr.hasNext(); ){
man.add( itr.next() );
}
System.out.println( man );
}
public void run(Collection<?> c){}
}
//2、泛型类,如果指定一个类为泛型类
/* 那么类所包含的方法都可以用到该泛型.
* 注意:此处在调用实例化泛型类的时候,
* 需要保持泛型和传入参数的类型一致。
* */
class Human<
YY>{
Human(
YY a){
System.out.println( a );
}
//3、泛型方法,如果在一个类中,想要有不同的泛型表示。
/* 那么可以把这个泛型定义在方法上。
* 注意此处
<TT>应该表示在返回值的前面
* */
public <TT> void say(TT b){
System.out.println( "" );
}
//4、静态泛型方法。
/* 静态泛型方法一旦被定义,就不能使用类的泛型,因为类的泛型需要被实例化。
因此,只能选择在方法内部定义方法。
public static void run(YY c){
} 此处编译报错 */
}
//5、泛型接口
/*
* 泛型接口:
一旦接口被定义泛型,
*
那么实现的时候一定要确定是何种数据类型
*
* 注意:、如果接口里的方法的参数用了泛型,
* 那么这个泛型要跟实现声明泛型保持一致
*/
interface Smoking<FF>{
public void lighter(FF q);
public void smoke();
}
class Mother{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Man extends Mother implements Smoking<String>{
private String name;
Man(){
this.name =
String.valueOf( (int)(Math.random() * 100) );
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void lighter(String a){
}
public void smoke(){
}
}
Map
Map 集合:<键值对>
就像是一本书的目录和内容,通常是通过目录去找内容。
Map
无序的:
1、增 put(key, value) putAll(Map<? extends K,? extends V> m)
2、删 clear remove(Object key)
3、改 put(K key, V value)
4、查 keySet entrySet get size
1、HashTable 同步的,Hash表的数据结构形式,速度慢
2、HashMap 不同步的,Hash表的数据结构形式,速度快
3、TreeMap 不同步的,Tree的数据结构形式,速度慢
获取键的形式,遍历:
1、keySet
2、entrySet
HashMAP 和 HashSet 区分与联系:
1、都是通过哈希表做为数据结构存储数据。
2、集合内部的数据都不重复。
3、HashSet 其实就是一种HashMap,只不过不存在相关的key,也就是取值的时候只能用迭代。
4、HashMap 没有迭代。需要转换成Set类型。
Map<String,String> map = new HashMap<String,String>();
map.put("userName", "jabez");
map.put("userSex", "1");
map.put("userAge", "18");
map.remove( "userAge" ); //移除键为userAge
map.put("userAge", "17");//Map一般通过键去改Value。
//遍历集合,通过keySet获取Map键,通过键获取值
Set<String> keys = map.keySet();
for( Iterator<String> itr = keys.iterator(); itr.hasNext(); ){
System.out.println( map.get(itr.next()) );
}
System.out.println( "=====" );
//遍历集合,通过entrySet获取Map的键以及获取Map的值
Set<Map.Entry<String, String>> keys1 = map.entrySet();
for( Iterator<Map.Entry<String, String>> itr = keys1.iterator(); itr.hasNext(); ){
Map.Entry<String, String> entry = itr.next();
System.out.println( entry.getValue() + "****" + entry.getKey() );
}
包装器
Collections:
包装器与众多集合类一样实现了Collection接口。
包装器里的方法都是由静态方法组成,可以直接通过类调用
包装器里的方法很多都是非常实用的:
fill、reverse、max、min、replaceAll、shuffle、sort\
fill:使用
指定元素替换指定列表中的所有元素。
reverse:反转指定列表中元素的顺序。
max: 取列表中最大的元素,按自然排序。
min:取集合中最小的元素,按自然排序。
replaceAll:使用另一个值替换列表中出现的所有某一指定值。
shuffle:打乱列表
sort: 自然排序,可重写比较器
高级for循环:在1.5之后有foreach
for( xx : yy )
高级for局限性:必须要有遍历的目标
可变参数 JDK 1.5 特性
其实一种数组参数的简写方式。
代替实例化的过程。
也称之为隐私封装数组.
可变参数原则:
1、
如果需要多个参数传入,请把其他的参数放在可变参数之前。
2、可变参数只有... ,比如 int... 表示传入的int的数组。
3、
一个函数只能拥有一个可变参数。
//可变参数
public static void run( int... age ){
for( int i = 0; i < age.length; i++ ){
System.out.println( age[i] );
}
}
//main中调用
run( 10,20,30,40,50,60,70,20 );
异常
异常有两种:
1.编译时被检测异常,该异常不需要抛出,也不需要进入监控区try,
但是会编译失败,一旦该异常被标识,证明它可处理
2.运行时异常,编译器不检查,该异常发生时,建议不处理,让程序停止,
此时要修改代码
异常就是一些你想不到的,
但是又偏偏就来到你身边的事情。
在开发中,一般这种异常可称之为 如:
文件找不到?网络连接失败?非法参数 等。
java里也有异常,它就是Exception。
throwable:
- Error
- Exception
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)
的实例时,才能通过 Java 虚拟机或者 Java
throw 语句抛出。类似地,只有此类或其子类
之一才可以是 catch 子句中的参数类型。
Exception:
- RuntimeException
- NullPointerException
- IndexOutOfBoundsException
- ...
- IOException I/O 异常
- ...
Exception 基本写法:
try{ //开始进入监控区
//throw new ArithmeticException(); 可选择主动抛出异常,相当于暗箱操作
}catch(Exception e){ //抓到你的把柄了
e.printStackTrack();
}catch(Exception e){ //catch写多个捕获异常,注意:建议Exception尽量写它的子类
}finally{
}
finally的就是,无论如何都是执行的代码块。
在以下几种情况,finally不会执行
1. finlly{
System.exit(0);//程序退出
System.out.println(0);
}
2.在finally里面发生了异常
3.程序所在线程死亡
4.关闭CPU
如何自定义异常?
1、在try中可以判断自己的值,再主动抛出异常。
2、throw new 自定义异常类。注意:自定义异常类一定要继承Exception父类
3.自定义异常必须extends Exception或者RuntimeException
4.让程序具有可抛性
5.让这个自定义异常类具有异常的共性方法
super(msg);
6.自定义异常也是为了针对异常进行封装使用
异常的好处:
1.将问题进行封装
2.将正常的代码和输出的问题代码分离,方便阅读
转载请注明原文地址: https://ju.6miu.com/read-1300195.html