JAVASE的学习笔记(五)(包装类与泛型)

包装类

为什么需要包装类

Java设计之初由一个基本原则:一切皆对象(先有类才有对象),一切的操作都是需要用对象的形式进行描述。

但是出现不是对象“东西”,基本数据类型不是对象,无法使用对象的形式来进行操作

创建对象之后,那么我们可以通过.运算符调用响应的属性和行为,操作基本数据类型也想使用对象的形式?

代码

public class Demo01{
    public static void main(String...args){
        int num = 100;
        //将基本数据类型int包装成temp的对象
        Int temp = new Int(100);
        //使用包装后的对象,调用行为或者属性
        temp.m1();
        
        //从对象中取得了基本数据
        int result = temp.intValue();
        System.out.println("result="+result);
    }
}
/**
* 实现基本数据类型int的包装类
*/
public class Int{
    private int number;
    
    public Int(int number){
        this.number = number;
    }
    
    public void m1(){
        System.out.println("number="+number);
    }
    //获取包装类中的数据
    public int intValue(){
        return this.number;//可以省略this
    }
}

系统包装类

在这里插入图片描述

数据类型转换(核心)★★

字符串java.lang.String和基本数据类型之间的转换

  • Integer类: public static int parseInt(String s) : Integer.parseInt(String s)
  • Double类: public static double parseDouble(String s)
  • Boolean类: `public static boolean parseBoolean(String s)
  • Character包装没有

包装类的使用

  • 装箱操作:将基本数据类型变成包装类,每个包装类的构造方法都可以接收各自数据类型的变量
  • 拆箱操作:从包装类中提取出包装的数据(基本数据类型),利用Number类提供的上述六个方法
    自动装箱拆箱:
public class Demo05{
    public static void main(String...args){
       Integer obj = 11;//自动装箱 int->Integer,不需要我们在使用构造方法了
       int temp = obj;//自动拆箱 Integer->int 实际上底层调用obj.intValue()方法
       //包装类可以进行计算
       obj++;//自动拆箱过程 obj->int
       System.out.println(obj);//自动装箱 int->Integer
       System.out.println(temp*obj);//自动拆箱Integer->int
    }
}

泛型

概念:泛型就是参数化的类型(传递),使用广泛的类型

使用泛型的原因?

数据类型不明确

  • 装入数据的类型(赋值)都被处理Object类型,从而“失去”了自己实际的类型
  • 往往我们在获取数据的时候,还需要转换数据类型,效率低下,并且十分容易产生错误

泛型的作用?

  • 安全性:在编译期间就检查数据类型是否安全(是否匹配)
  • 省心(高效性):所有的强制类型转换都是变成自动(隐藏)的,提高了代码的重用率

如何定义泛型?

定义格式:使用<任意的字母>符号

泛型中常用的字母含义(约定)

  • T : Type表示类型
  • K,V : 代表键值对Key和Value
  • E:代表Element
  • N:代表Number数字
  • ?:表示不确定性

泛型的使用规则

(1)不能使用静态属性上,static修饰的不能使用泛型★★★

(2)使用的时候需要指定数据类型:
    a.编译的时候会检查数据的类型
    b.获取数据的时候不再需要强制类型转换

(3)泛型使用是不能指定基本数据类型,只能使用基本数据类型对应的包装类

使用泛型定义接口,我们称之为泛型接口,因为泛型中只能由公共的抽象方法静态公共常量(不能使用泛型 。接口中,泛型字母只能使用在方法中,不能使用在全局变量中 因为接口只包括全局常量和公共、抽象方法,而全局变量是static的,所以不能用,所以只能用在方法中),JDK8之后可以定义普通的默认方法和静态的默认方法

泛型的使用范围

(1)泛型类:public class Student01<T1,T2>
(2)泛型接口

public interface Info<T>{
    T getVar();
    void setVar(T value);
}

a.非泛型类实现接口:声明的子类实现接口必须指定“具体的类型”

public class InfoImpl01 implements Info<Double>{   
    private Double var;
    
    public Double getVar(){
        return var;
    }
    
    public void setVar(Double var){
        this.var = var;
    }

}
public class Demo05{
    public static void main(String[] args){
        //Info<String> info = new InfoImpl01();
        
        Info<Double> info = new InfoImpl01();
        info.setVar(123.456);
        System.out.println(info.getVar().getClass());
              
    }
}

b.泛型类实现接口

public class InfoImpl02<U> implements Info<U>{   
    private U var;
    
    public U getVar(){
        return var;
    }
    
    public void setVar(U var){
        this.var = var;
    }

}

(3)泛型方法:没有使用泛型类,也没有使用泛型接口,直接在方法上使用泛型

public class FunsTest{
   
   //普通方法
   public <T> int test01(T num){
       System.out.println(num);
       System.out.println(num.getClass());
       return 100;
   }
   public <T> T test02(T num){
       System.out.println(num);
       System.out.println(num.getClass());
       return num;
   }
   //静态方法
   public static <T> String test03(T num){
       System.out.println(num);
       System.out.println(num.getClass());
       return "悟空";
   }
   public static <T> T test04(T num){
       System.out.println(num);
       System.out.println(num.getClass());
       return num;
   } 
}
public class Demo06{
    public static void main(String[] args){
       FunsTest ft = new FunsTest();
       ft.test01("悟空");//没有在编译期间检查数据的类型
       //会自动将<T>自动变成String,数据决定泛型的类型
       //编译不会产生错误
       /**不符合规范的,但是是推荐使用*/
       
       //标准写法,不推荐使用
       ft.<Integer>test01("八戒");//编译检查了数据类型
              
    }
}

(4)泛型数组
private T[] array ;//只能声明,不能创建

public class Demo07{
   public static void main(String[] args){
       Dog<String> dog = new Dog<>();
       
       Integer[] temp = m1(1,2,3,4);
       System.out.println(java.util.Arrays.toString(temp));
       
       String[] temp01 = m1("悟空","八戒");
       System.out.println(java.util.Arrays.toString(temp01));
       
   }
   
   public static <T> T[] m1(T...array){
       return array;
   }
}
class Dog<T>{
  // private T[] array = new T[10];//不能创建
   private T[] array ;//只能声明
   

}
泛型类型之间不存在转换,没有所谓的对象上转型,接口回调
  1. Student无法转换为Student<0bject>
public class Demo01 {
public static void main(String.. . args){
	Student<String> s1 = new Student<>();
	s1. setMath("良好”);
	s1. setEnglish("中等");
	//s1数据就可以传递了
	//调用m1方法Student<String>->Student<0bject>
	//泛型类型之间转换?
	m1(s1);
	//错误:不兼容的类型: Student<Str ing>无法转换为Student<0bject>
	}
public static void m1 (Student<0bject> temp){
	System . out . println(" temp=+temp) ;
	}
}

2.修改代码,将m1中的泛型不指定类型,不指定T就是Object,这种情况违背了使用泛型的意图,丢失了原本的类型,又需要判断类型进行强转

public class Demo02{
    public static void main(String...args){
        Student<String> s1 = new Student<>();
        s1.setMath("良好");
        s1.setEnglish("中等");
        //s1数据就可以传递了
        m1(s1);
        
        
    }
    //Student不写泛型的范围比Student<Object>范围大
    public static void m1(Student temp){
        //不兼容的类型: Object无法转换为String
        //又丢失了你原本的类型,我们又需要判断类型进行强转
        String math = temp.getMath();
        System.out.println("temp="+temp);
    }
}
  1. ? 通配符:根据你传递的泛型变化而变化
受限的泛型(限定泛型)
  • 上限限定使用extends关键字,表示这个类型必须是继承某个类或者实现某个接口,也可以是该类的本身或接口的本身
public class Person<T extends Number>
  • 下限限定使用super关键字,表示类型是某个类的父类或者是某个接口的父接口,也可以是这个类的接口本身
public class Person<T super Number>//错误:下限限定使用super关键字,不能使用在泛型类和泛型接口中
  • 下限限定使用super关键字,不能使用在泛型类和泛型接口中,一般我们使用在泛型的方法传递中
public static void m1(Person<? super Double> temp){
        System.out.println(temp);
    }

泛型擦除规则

  • 声明实现类,实现的接口必须指定"具体的类型"
    class Service01 implements UserService<String>{}

  • 实现类和接口同时擦除(不写),使用Object
    class Service02 implements UserService{
    public void add(Object t){}}

  • 实现类是泛型,实现的接口擦除,使用Object
    class Service03<T> implements UserService{
    public void add(Object t){}}

  • 实现类是泛型,实现的接口泛型,泛型相等
    class Service04<U> implements UserService<U>{
    public void add(U t){}}

  • 错误:实现类擦除,接口泛型

public interface UserService<T>{
    void add(T t);
}
//声明实现类,实现的接口必须指定"具体的类型"
class Service01 implements UserService<String>{
    public void add(String t){
        
    }
}
//实现类和接口同时擦除(不写),使用Object
class Service02 implements UserService{
    public void add(Object t){
        
    }
}
//实现类是泛型,实现的接口擦除,使用Object
class Service03<T> implements UserService{
    private T value;
    
    public void add(Object t){
        
    }
}
//实现类是泛型,实现的接口泛型,泛型相等
class Service04<U> implements UserService<U>{
    public void add(U t){
        
    }
}
class Service05<X,Y,Z> implements UserService<Y>{
    public void add(Y t){
        
    }
}
//错误:实现类擦除,接口泛型
/*
class Service06 implements UserService<Y>{
    public void add(Y t){
        
    }
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月色夜雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值