1.方法可变参数
含义:将可变参数变成一个数组,通过数组访问可变参数;
规则:
- public [static] [final] 返回值 方法名称([参数类型 参数名称],参数类型...参数名称) {}
- 可变参数必须定义在参数列表最后;
- 可变参数在参数列表中最多一个;
package bit;
/**
*
*/
public class TestDemo {
public static void main(String[] args) {
System.out.println(add(1,2,3));
System.out.println(add(1,2,3,4));
System.out.println(add(1,2,3,4,5));
}
public static int add(int... values) {
int sum=0;
for (int value:values) {
sum+=value;
}
return sum;
}
}
2.泛型类
- 类名<类型参数>
- 在实例化对象是,变量类型中必须指定类型参数的具体类型 并且必须使用引用数据类型(如果使用基本数据类型必须转换成包装类型),若在实例化对象时为指定类型参数编译器统一认为类型参数为Object类型参数;在构造方法中可以省略类型参数的具体类型,但<>不可省;
Point<String> point1= new Point<>();
- 使用了类型参数的属性的类型即是类型参数的具体类型;
- 泛型类的类型参数可以设定多个
package bit;
/**
*
*/
class Point<T,E> {
private T x;
private E y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public E getY() {
return y;
}
public void setY(E y) {
this.y = y;
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
public class TestPoint{
public static void main(String[] args) {
Point<String,String> point1= new Point<>();
point1.setX("东经30度");
point1.setY("北纬20度");
Point<Integer,Integer> point2=new Point<>();
point2.setX(12);
point2.setY(34);
System.out.println(point1);
System.out.println(point2);
}
}
3.泛型方法
- public <类型参数> 返回值类型 方法名([参数化类型 参数名称]) {}
- 泛型方法时独立定义(可单独定义泛型方法,和类没有直接关系)
- 泛型方法的类型参数是在方法返回值类型的前面定义,并且可定义多个,返回值类型可以为类型参数,但返回值类型只有一个
package bit;
/**
*
*/
class Point<T,E> {
private T x;
private E y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public E getY() {
return y;
}
public void setY(E y) {
this.y = y;
}
public <T> T testMethod(T t) {
return t; //泛型方法
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
public class TestPoint{
public static void main(String[] args) {
Point<String,String> point1= new Point<>();
System.out.println(point1.testMethod(10)); //泛型方法的调用
}
}
4.通配符 <?>
- ?表示通配符,可以接收任意的类型参数的类型,但对象不能再次修改
- ? extends classType 泛型上限, ?类型是classType 或它的子类
- ? super classType 泛型下限,?类型是classType或它的父类
- 泛型上限可以应用到类和方法中,引用到方法中,参数值不可修改
- 泛型下限不可以应用到类中,可应用到方法中,参数值可以修改(修改为泛型下限的子类任意类型 [我个人的理解为如果修改为泛型下限的父类那么返回之后,因为原先实例化对象的所属类为该返回的子类,那样就会出现实例化对象在调用某个方法后,用户并不是有心调用它的父类,所以会对本身的一些钩子方法不能调用,从而会破坏前后逻辑. 而如果修改为实例化对象下限的子类,那样肯定能够调用本身所有的方法,不会破坏前后逻辑,所以编程语言支持修改] )
/**
*
*/
class Myclass<T extends Number> { //只有泛型上限才能应用到类中,
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
@Override
public String toString() {
return "Myclass{" +
"x=" + x +
", y=" + y +
'}';
}
}
public class TestMyclass{
public static void main(String[] args) {
Myclass<Number> myclass=new Myclass<>();
fun(myclass);
}
public static void fun(Myclass<? super Number> myclass) {
myclass.setX(33.3); //可以修改为Number的子类 Double
System.out.println(myclass.getX());
}
}
5.泛型接口
- interface 接口名<类型参数>{}
- 实现 ①实现类保留类型参数 implementclass<类型参数> Implements interface<类型参数>{}
- 实现 ②实现类不保留类型参数 implementclass Implements interface<String>{} 此时类型参数必须明确给出具体类型 该实现类同普通类性质相同
package bit;
/**
*
*/
public class TestMessage {
public static void main(String[] args) {
IMessage<String> qqMessage=new QQMessage<>();
IMessage msnMessage=new MSNMessage();
System.out.println(qqMessage.print("你好"));
System.out.println(((MSNMessage) msnMessage).print("你好"));
}
}
interface IMessage<T> {
T print(T t);
}
class QQMessage<T> implements IMessage<T> {
@Override
public T print(T t) {
return t;
}
}
class MSNMessage implements IMessage<String > {
@Override
public String print(String s) { //运用开发工具,在接口指定具体的数据类型时,该方法的覆写接口返回值自动设置为具体的数据类型
return s;
}
}