泛型:JDK1.5后出现的特性,用于解决安全问题,是一个类型安全机制。
注:此章泛型为基础部分,高新技术泛型见高新技术部分。
好处:
1.将运行时期出现的问题ClassCastException,转移到编译时期。方便程序员解决问题。让运行期间问题减少,安全。
2.避免了强制转换麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见。
只要见到<>就要定义泛型。
其实<>就是用来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*;
class GenericDemo
{
public static void main(String[] args)
{
ArrayList<String> al=new ArrayList<String>();//<>泛型,强制指明存放数据的类型
al.add("abc01");
al.add("0991");
al.add("abc014");
Iterator<String> it=al.iterator();
while(it.hasNext())
{
String s=it.next();//现在省去了(String)it.next()写法
System.out.println(s+":"s);
}
}
}
class LenComparator implements Comparator<String>
{
public int compare(String o1,String o2)//此处直接写String o1而不用Object obj了
{
int num=new Integer(o1.lelngth()).compareTo(new Integer(o2.length()));
if(num==0)
return o1.compareTo(o2);
return num;
}
}</span>
//泛型类
/*什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期要定义Object来完成扩展。现在定义泛型来完成扩展。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">class Tool<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q=q;
}
public QQ getObject()
{
return q;
}
}
class GenericDemo
{
public static void main(String[] args)
{
Tool<Worker> u=new Tool<Worker>();
u.setObject(new Worker());//当写成(new Student)时即报错,因为定义了Tool类只接收Worker类型
Worker w=u.getObject();
}
}
class Student
{
}
class Worker
{
}
</span>
/*上述程序将 泛型定义在类上,那么该泛型在整个类中有效,那么该类中的方法,能操作的类型也就固定了。
为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">class Demo
{
public <T> void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void println(Q q)
{
System.out.println("print:"+q);
}
}
class GenericDemo4
{
public static void main(String[] args)
{
Demo d=new Demo ();
d.show("hahah");//处理字符型
d.println(Integer(4));//处理整型
}
}</span>
/*静态方法泛型用法*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">class Demo<T>
{
public void show(T t)
{
System.out.println("show"+t)
}
public <Q>void println(Q q)
{
System.out.println("print:"+q);//在类中定义了泛型后,类中的方法也可以再定义泛型,就和类中的泛型没关系了。
}
public static <W>void method(W t)//在非静态类中定义静态方法,编译错误,因为当该方法初始化时,该方法中的泛型类,还没出现,出错。
{
System.out.println("method:"+t);
}
}
class GenericDemo4
{
public static void main(String[] args)
{
Demo<String> d= new Demo<String>();
d.show("haha");
//d.show(4);//出错,因为类的泛型是String型,类中普通方法默认泛型为Sting型
d.print(5);//正确,自定义泛型方法
d.print(5);//正确,自定义泛型方法
}
}
</span>
/*泛型定义在接口上*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">interface Inter<T>
{
void show(T t)
}
class InterImpl<T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
}
class GenericDemo5
{
public static void main(String[] args)
{
InterImpl<Integer> i=new InterImpl<Integer>();
i.show(4);
}
}
</span>
/*泛型高级应用:泛型限定
?:通配符,也可理解为占位符。
泛型的限定:
?extend E:可以接受E类型或者E的子类型。有上限。
?super E:可以接受E类型或者E的父类型。有下限。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">class Person
{
private String name;
Person(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
}
class GenericDemo6
{
public static void main(String[] args)
{
ArrayList<Person> al=new ArrayList<Person>();
al.add(new Person("abc1"));
al.add(new Person("abc2"));
al.add(new Person("abc3"));
ArrayList<Student>al2=new ArrayList<Student>();
al2.add(new Student("abc--1"));
al2.add(new Student("abc--2"));
al2.add(new Student("abc--3"));
printColl(all);
}
public static void printColl(ArrayList<? extends Person> al)//只能接受E类型或者E的子类型
{
Iterator<? extends Person> it=al.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
</span>
/*泛型限定2*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*;
class GenericDemo7
{
public static void main(String[] args)
{
TreeSet<Student> ts=new TreeSet<Student>(new Comp());//通用比较器,Person比较器
ts.add(new Student("abc03"));
ts.add(new Student("abc02"));
ts.add(new Student("abc06"));
ts.add(new Student("abc01"));
Iterator <Student>it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
TreeSet<Worker> ts1=new TreeSet<Worker>(new Comp());//通用比较器,Person比较器
ts.add(new Worker("wabc--03"));
ts.add(new Worker("wabc--02"));
ts.add(new Worker("wabc--06"));
ts.add(new Worker("wabc--01"));
Iterator <Worker> it1=ts1.iterator();
while(it.hasNext())
{
System.out.println(it1.next().getName());
}
}
}
class Comp implements Comparator<Person>//父类Person的比较器
{
public int compare(Person p1,Person p2)
{
return p2.getName().compareTo(p1.getName());
}
}
class Person
{
private String name;
Person(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
}
class Worker extends Person
{
Worker(String name)
{
super(name);
}
}</span>
其他对象:System:类中的方法和属性都是静态的。
out:标准输出,默认是控制台。
in:标准输入,默认是键盘。
描述系统的一些信息。
获取系统属性信息:Properties getProperties();
import java.util.*;
class SystemDemo
{
public static void main(String[] args)
{
Properties prop=System.getProperties();
//因为Properties是Hashtable的子类,也就是Map集合的一个子类对象。
//那么可以通过map的方法取出给集合中的元素。
//该集合中存储都是字符串,没有泛型定义。
//如何在系统中自定义一些特有信息呢?
System.setProperty("maykey","myvalue");
//获取指定属性信息。
String value=System.getProperty("os.name");
System.out.println("value="+value);
//可不可以在jvm启动时,动态加载一些属性信息呢??
String v=System.getProperty("haha");
System.out.println("v="+v);
//获取所有属性信息
for(Object obj:prop.keySet())
{
String value1=(String)prop.get(obj);
System.out.println(obj+"::"+value1);
}
}
}
/*Runtime对象。
该类并没有提供构造函数。
说明不可以new对象,那么会直接想到该类中的方法都是静态的。
发现该类中还有非静态方法。
说明该类肯定会提供了方法获取本类对象,而且该方法是静态的,并返回值类型是本类类型。
这个特点可以看出该类使用了单例设计模式。
由
该方法是static Runtime getRuntime();
class RuntimeDemo
{
public static void main(String[] args)throws Exception
{
Runtime r = Runtime.getRuntime();//获得该类对象。
Process p=r.exec("C:\\PDF.EXE");//\默认为转义字符,\\将\变为普通符合。
Thread.sleep(4000);
p.destroy();
}
}
/*对象:Date*/
import java.util.*;
import java.text.*;
class DateDemo
{
public static void main(String[] args)
{
Date d=new Date();
System.out.println(d);//打印的时间看不懂,希望有些格式。
//将模式封装到SimpleDateformat对象。
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
//调用format方法让模式格式化指定Date对象。
String time=sdf.format(d);//format:格式化日期
System.out.println("time="+time);
}
}
/*Calendar对象*/
import java.util.*;
import java.text.*;
class CalendarDemo
{
public static void printCalendar(Calendar c)
{
/*
Date d=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy");
String year=sdf.format(d);
System.out.println(time);
*/
String[] mons={"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
int index=c.get(Calendar.MONTH);
String[] weeks={"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
int index1=c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop(c.get(Calendar.MONTH)+1)+"月")
sop(mons[index]);//月
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
}
public static void main(String[] args)
{
Calendar c =Calendar.getInstance();//Calendar实例
c.set(2011,3,4);//设置时间。
c.add(Calendar.YEAR,4);//对时间量的偏移,可任意加减时间。
c.add(Calendar.DAY_OF_MONTH,4);
printCalendar(c);//打印时间。
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
/*两个小练习:
1.获取任意年的二月有多少天。
思路:根据指定年设置一个时间就是:
c.set(year,2,1)//某一年的3月1日。
c.add(Calendar.DAY_OF_MONTH,-1);//3月1日,往前推一天,就是2月最后一天。
2,获取昨天的现在这个时刻。
c.add(Calendar.DAY_OF_MONTH,-1);
*/
/*Math-Random*/
import java.util.*;
class MathDemo
{
public static void main(String[] args)
{
double d3=Math.random();//random返回0.0<=d3<=1.0的任意数。
sop(d3);
Random r=new Random();//JDK中其实提供了随机类Random
for(int x=0;x<10;x++)
{
//int d4=(int)(Math.random()*10);//返回0-10的整数
int d4=r.nextInt(10);//返回0-10的整数
sop(d4);
}
}
public static void show()
{
double d=Math.ceil(-16.44);//ceil返回大于指定数据的最小正数。
double d1=Math.floor(12.44);//floor返回小于指定数据的最大整数。
long l=Math.round(12.43);//round四舍五入
double d2=Math.pow(2,3);//2的3次幂
sop("d"+d);
sop("d1"+d1);
sop("l"+l);
sop("d2"+d2);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}