泛型:
在创建集合的时候给定集合的类型,就是将参数化,类似于方法中的变量参数,此时类型也定义成参数形式(也可以称为形参),然后在使用/调用传入具体的类型(类型实参) 方便后续不用做强制类型转换操作
ps:泛型只作用于编译期检查,在编译后,会被擦除
泛型类:
在定义类是可以定义泛型,可以使用同样类型的接口
比如:
public class Demo<T> {
//ex的类型有T来定义
private T ex;
public Demo(T ex) {//有参构造,T为外部指定类型
super();
this.ex = ex;
}
public T getEx() {//创建获取ex的方法 ,其类型也为T
return ex;
}
public void setEx(T ex) {
this.ex = ex;
}
}
Demo<Integer> demo=new Demo<Integer>(123456);
Demo<Number> demo1=new Demo<Number>(20);
泛型接口:
接口类型也可以定义泛型,和泛型类相似
public interface Generic<T> {
public T sth();
}
public class GenericTest<T> implements Generic<T> {
//未传入泛型实参时
@Override
public T sth() {
return null;
}
}
public class GenericTest2 implements Generic<String>{
private String[] name={"小迷","小明","小花"};
//传入泛型实参
@Override
public String sth() {
Random rd=new Random();
return name[rd.nextInt(3)];
}
}
通配符:
在调用不同的参数是,会出现方法不能输出结果,而如果每一个泛型都需要写一个方法的花太过于繁琐,因此,需要使用通配符来输出泛型
/**
* 使用通配符后不管参数为什么类型的泛型,都可以使用方法输出
* 注意:由于不知道会传入什么类型的数据,所以通配符只能读取数据,不能修改
*/
private static void getDate1(Demo<?> demo) {
System.out.println(demo.getEx());
}
/**
* 通配符上限
* extends 表示只能输出其自身及其子类
* @param demo
*/
private static void getDate2(Demo<? extends Number> demo) {
System.out.println(demo.getEx());
}
/**
* 通配符下限
* super 表示只能输出其自身及其父类
* @param demo
*/
private static void getDate3(Demo<? super Number> demo) {
System.out.println(demo.getEx());
}
getDate(demo);
getDate1(demo1);
getDate2(demo);
getDate2(demo1);
// getDate3(demo); 报错,Integer是Number的子类不能输出
getDate3(demo1);
泛型方法:
在方法中可以使用泛型,在调用时可以直接使用
/**
* 泛型方法
*
* @param <T>
* @param array
* @param i
* @param j
* @return
*/
private static <T> T[] funs(T[] array,int i,int j) {
T temp=array[i];
array[i]=array[j];
array[j]=temp;
return array;
}
String [] array={"tom","jack","loij","rose"};
String[] result= funs(array, 1, 2);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
运行结果:
tom
loij
jack
rose
泛型的嵌套使用:
Map<Integer, String> map=new HashMap<Integer, String>();
map.put(1,"小米");
map.put(2,"小明");
Set<Map.Entry<Integer, String>> set=map.entrySet();
for (Entry<Integer, String> entry : set) {
System.out.println(entry);
}
运行结果:
2:实用类
1:枚举:
是由一组固定常量组成的类型
public enum Genders {//枚举
男,女
}
public class Student {
public String name;
public Genders gender;
}
public class StudentTest {
public static void main(String[] args) {
//无参构造创建对象
Student stu=new Student();
stu.name="小明";
stu.gender=Genders.男;
}
}
2:包装类:
- 1介绍:在java中有八大基本数据类型,同时java提供了基本类型中的包装类(Byte,Short, Integer,Long,Float,Double,Chareter,Boolean),这些类在创建对象时和类new对象一致
Integer in=new Integer(123);//要表明指定的值
Integer in1=new Integer("123");// String 参数所指示的 int 值
- 2包装类中拆箱,装箱操作
//需要会实现基本数据类型和包装类之间 的装换操作
Integer num=new Integer(1);//装箱操作
int num1=num.intValue();//拆箱操作
//为了方便,可以直接进行自动装箱和拆箱
Integer num2=10;//自动装箱
int num3=num2;//自动拆箱
- 3包装类中new()和valueOf()的区别
总所周知,使用包装类是可以使用new或者valueOf来形成新的对象,但是其是存在差异的,其表现在包装类中的缓存机制
Integer num=10;
Integer num1=10;
Integer num2=new Integer(100);
Integer num3=new Integer(100);
Integer num4=130;
Integer num5=130;
System.out.println((num==num1) +" "+ num.equals(num1));
System.out.println((num2==num3) +" "+ num2.equals(num3));
System.out.println((num4==num5) +" "+ num4.equals(num5));
运行结果:
true true
false true
false true
可以得到在Integer创建对象的时候,num和num1都是相同的对象,范围在-128~127之间 由于num4和num5超出取值,所以创建了两个不同的对象,在==比较的时候是不相同的num2与num3都是属于new出来的不同的两个对象,==比较的Integer创建的对象,所以不相同.
- 4包装类的优点
说了那么多.可能理解包装类是怎么创建,怎么转换的,那么包装类在开发之中到底有什么用呢???
众所周知,java是一门面向对象的语言,然而在我们的开发过程中都是直接创建基本类型,而我们把常用的基本类型放在类里面,使用的时候进行调用,就很方便了.在某些特定的场所,基本数据类型不能使用,这时候就能体现包装类的强大了.
其次在编程的过程,内存和运行速度是有限的,每次我们new一个对象都是在占用内存,非常的浪费资源,当将基本数据类型进行包装后,我们可以通过类来调用数据,就非常的节约资源了.