美文网首页
JavaWeb (day7)

JavaWeb (day7)

作者: 定格r | 来源:发表于2019-04-16 22:17 被阅读0次

    1.泛型的简介

    1.1为什么要使用泛型

    一般使用在集合上

    比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放入到集合之后,失去本来类型,只能是 object 类型,这个时候,比如想要对这个值进行类型转换,很容易出现类型转换错误,怎么解决这个问题,可以使用泛型类来解决。

    1.2在集合上如何使用泛型

    • 常用的集合 list set map

    • 泛型语法 集合<String> 比如 List<String>

    1.3 、在泛型里面写是一个对象 Stirng 不能写基本数据类型

    写基本数据类型的包装类

    • byte —— Byte
    • short —— Short
    • int —— Integer
    • long —— Long
    • float —— Float
    • double —— Double
    • char —— Character
    • boolean —— Boolean

    2.泛型类的使用

    2.1、泛型类在 list 上的使用

    代码:

    List <String> list=new ArrayList<String>();
    list.add("aaa") ;
    list.add("bbb") ;
    list.add("ccc") ;
    //遍历 list
    
    //普通 for 循环
    for(int i=0;i<list.size();i++){
    String s=list.get(i);
    System.out.print(s);
    }
    //使用增强 for
    for(String s1:list){
    System.out.print(s1);
    }
    //使用迭代器遍历
    Iterator<String> it=list.iterator();
    while(it.hasNext()){
    System.out.print(it.next());
    }
    

    2.2、泛型使用在 set 集合上

    set 集合特点:无序,唯一
    代码:

    Set <String> set=new  HashSet<String>();
    list.add("www") ;
    list.add("qqq") ;
    list.add("zzz") ;
    //遍历 set ,有两种方式
    //for(String   s2 : set){
    System.out.print(s2);
    }
    //使用迭代器遍历
    Iterator<String> it1=set.iterator();
    while(it1.hasNext()){
    System.out.print(it1.next());
    }
    

    2.3、在 map 上使用泛型

    代码:

    Map<String,String> map=new HashMap<String,string>();
    map.put("aaa","111");
    map.put("bbb","222");
    map.put("ccc","333");
     //遍历 map 有两种遍历方式
    //1.获取所有的 key,通过 key 得到 value 使用 get 方法
    //获取所有的 key
    Set<String> sets=map.keySet();
    //遍历所有 key 返回的 set
    for(String key:sets){
    String value=map.get(key);
    System.out.print(key+“    : ”+value);
    }
    
    //2.获取 key 和 value 的关系
    Set <Entry<String,String>> sets1 =map.entrySet();
    for(Entry<String , String> entry : sets1){
    String keyv=entry.getKey();
    String valuev=entry.getValue();
    System.out.print(keyv+":"+valuev);
    } 
    

    2.4 泛型使用在方法上

    定义一个数组,实现指定位置上数组元素交换

    方法逻辑相同,只是数据类型不同,这个时候使用泛型方法

    public static <T> void swap1(T[] arr,int a,int b){
    T temp =arr[a];
    arr[a]=arr[b];
    arr[b] =temp;
    }
    

    2.5 泛型在类上的使用

    代码:

    public class Test<T>{
    T   aa;
    public void test1(T   bb){}
    //写一个静态方法在类上面定义泛型,不能在静态方法里面使用
    public static <A> void test2(A  cc1){}
    }
    

    3.枚举的简介

    3.1、什么是枚举

    • 需要在一定的范围内取值,这个值只能是这个范围内的任意一个
    • 现场取景:交通信号灯,有三种颜色,但是每次只能亮三种颜色里面的任意一个

    使用一个关键字 enum

    enum Color3{
    RED 、 GREEN 、 YELLOW
    }
    

    枚举的构造方法也是私有的

    3.2 特殊的枚举操作

    • 在枚举里面有构造方法
      ——构造方法有参数,需要在每个实例上都写参数
    • 在枚举里面有抽象方法
      ——在枚举的每个实例里面都重写这个构造方法
    enum color{
    RED("red") {
    public   void  print1(){
    System.out.print("red");
    }
    },GREEN("green")
     {
    public   void  print1(){
    System.out.print("green");
    }
    },YELLOW("yellow") {
    public   void  print1(){
    System.out.print("yellow");
    }
    }
    //构造方法
    private color(String  name){
    }
    //抽象方法  --  在枚举的每个实例里面都重写这个构造方法
    public  abstract  void  print1();
    }
    

    4.枚举 api 的操作

    • name():返回枚举的名称
    • ordinal():枚举的下标,下标从零开始
    • valueof(class<T> enumType,String name):得到枚举的对象
      还有两个方法,都是这两个方法不在 api 里面,编译的时候生成两个方法
    • valueof(String name)转换枚举对象
    • values()获得所有枚举对象数组

    练习:
    1.知道枚举对象,得到枚举名称和下标

    public void test(){
    color     c100=color.RED;
    String  name=c100.name;  //得到枚举名称
    int idx=c100.ordinal();//得到枚举下标
    }
    enum color(
    RED,GREEN,YELLOW
    )
    

    2.知道枚举名称,得到枚举对象和下标

    public void test(){
    String  name1="GREEN";
    color  c1=color.valueOf(name1);//得到枚举对象
    int idx=c1.ordinal();//得到枚举下标
    }
    enum color(
    RED,GREEN,YELLOW
    )
    

    3.知道枚举下标,得到枚举对象和名称

    public void test(){
    int   idx2=2;
    color[]  cs=color.values();//得到枚举对象数组
    color  c2=cs[idx2];  //根据下标得到对象
    String  name=c2.name(); //根据对象得到名称
    }
    enum color(
    RED,GREEN,YELLOW
    )
    

    5.自动拆装箱

    装箱:把基本的数据类型转换成包装类
    拆箱:把包装类转换成基本的数据类型

    //自动装箱
    Integer  i=10;
    //自动装箱
    int m=1;
    

    在 jdk 1.4里面如何实现装箱和拆箱

    public void  test1(){
    //装箱
    Integer  m = new  Integer(10);
    //拆箱
    int  a = m.intValue();
    }
    

    jdk 向下兼容

    ——比如: jdk 1.4 里面写的代码,这个时候到 5.0 里面也可以运行

    6.增强 for 循环

    1.语法:

    for( String  s :  list){
       System.out.println(s);
    }
    

    2.使用场景:

    • 数组:实现 Iterable 接口的集合 可以使用增强 for 循环

    3.在集合上使用增强 for 循环遍历

    • list set 实现 Iterable 接口,所以可以使用增强 for 循环

    • map 不能使用增强 for 循环,没有实现 Interator 接口,所以不能使用

    4.增强 for 循环出现的目的:为了替代迭代器
    增强 for 底层就是迭代器实现的

    7.内容补充

    练习:实现一个泛型方法,接受任意类型的数组,颠倒数组中的所有元素

    public  static  <T> void  reverse(T[]  arr1){
    for(int i=0;i<arr1.length/2;i++){
     T temp =arr1[i];
     arr1[i]=arr1[arr1.length-i-1];
     arr1[arr1.length-i-1]=temp;
    }
    }
    

    8.可变参数

    应用场景:
    实现两个数相加,实现三个数相加,四个数相加

    如果实现多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数个数,这时候可以使用可变参数

    1.可变参数定义方法

    数据类型...数组名称
    可以理解为一个数组,这个数组存储传递过来的参数

    public static void add1(int...nums){
    int sum=0;
    for(int i=0;i<nums.length;i++){
    sum+=nums[i];
    }
    System.out.print(sum);
    //输出结果:
    //30
    //60
    //100
    }
    public static void main(String[] args){
    add1(10,20);
    add1(10,20,30);
    add1(10,20,30,40);
    }
    

    注意的地方:
    (1)可变参数需要写在方法的参数列表中,不能单独定义
    (2)在方法的参数列表中只能有一个可变参数
    (3)方法的参数列表中的可变参数,b必须放在参数最后

    add1(int  a , int...nums)
    

    9.反射

    9.1 反射的原理

    1.应用在一些通用性比较高的代码中

    2.后面学到的框架,大多数都是使用反射来实现的

    3. 在框架开发中,都是基于配置文件开发的
    ——在配置文件中配置了类,可以通过反射得到类中的 所有内容,可以让类中的某个方法来执行
    4.类中的所有内容:属性、没有参数的构造方法、有参数的构造方法、普通方法
    5.画图分析反射的原理

    1.首先需要 java 文件保存到本地硬盘 .java
    2.编译java 文件,成 .class文件
    3.使用 jvm ,把 class 文件通过类加载加载到内存中
    4.万事万物皆是对象,class 文件在内存中使用 class 类表示
    5.当使用反射的时候,首先需要获取到class 类,得到了这个类之后,就可以得到 class 文件里面的所有内容——包含属性,构造方法,普通方法
    6.属性通过一个类 Filed
    7.构造方法通过一个类 constructor
    8.普通方法通过一个类 Method

    9.2 使用反射操作类里面的属性

    • 首先获取到 class 类
         Class clazz1=person.class;
         Class clazz2=new person().getClass();
         Class clazz3=Class.forName("day06.person");
    
    • 操作无参数的构造方法
    public void test1() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            //得到 class
            Class c3=Class.forName("day06.person");
            //得到 person 实例
            person p=(person)c3.newInstance();
            //设置值
            p.setName("zhangsan");
            System.out.println(p.getName());
        }
    
    • 操作有参数的构造方法
    public void test2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            Class c1=Class.forName("day06.person");
            //传递有参数的构造方法里面的参数类型,类型使用 class 形式传递
            Constructor  cs=c1.getConstructor(String.class,String.class);
            //通过有参数的构造方法设置值
            person p1=(person) cs.newInstance("lisi","100");
            System.out.println(p1.getId()+" "+p1.getName());
        }
    
    • 使用属性来操作属性
    public void test3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            try {
            Class cc=Class.forName("day06.person");
            //得到 person 类的实例
            person p=(person) cc.newInstance();
            //通过这个方法得到属性,参数是属性的名称
            Field f1=cc.getDeclaredField("name");
            //操作的是私有属性,不让操作,需要设置可以操作私有属性setAccessible(true)
            f1.setAccessible(true);
            //设置name的值
            f1.set(p , "wangwu");//相当于 p.name="wangwu"
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
    
    • 使用泛型操作普通方法
      使用 Method 类表示普通方法
        public void test4() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            
            Class c4=Class.forName("day06.person");
            //得到 person 实例
            person p4=(person) c4.newInstance();
            //得到普通方法
            //传递两个参数,第一个参数:方法名称第二个参数:通过方法设置的值
            Method  m1=c4.getDeclaredMethod("setname", String.class);
            //让 setName方法执行,执行设置值
            m1.invoke(p4, "niuqi");
           System.out.println(p4.getName());
        }
        
    

    相关文章

      网友评论

          本文标题:JavaWeb (day7)

          本文链接:https://www.haomeiwen.com/subject/gzyiwqtx.html