JAVA基础——泛型、一些常用的类

时间:2022-04-26 21:52:11

     泛型(Generic

一、概述

1JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。

2JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类型的数据,无法加入指定类型以外的数据。

3、泛型是提供给javac编译器使用的可以限定集合中的输入类型说明的集合时,会去掉“类型”信息,使程序运行效率不受影响,对参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。

4、由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,如用反射得到集合,再调用add方法即可。

5、没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,可以将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全;并且当从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。

6、格式:

       通过<>来定义要操作的引用数据类型

      如:ArrayList<String>  //定义要存入集合中的元素指定为String类型

7、好处

       a、将运行时期出现的问题ClassCastException,转移到了编译时期。方便于程序员解决问题。让运行时期问题减少、安全。

       b、避免了强制转换的麻烦。如在实现某一个接口时,指定传入接口方法的实参的类型的话,在复写该接口方法时就可以直接使用指定类型,而不需要强制转换。

泛型研究:

      只有类被定义成了泛型,才可以对其进行参数化应用。

二、泛型定义中的术语:

        如:ArrayList<E>类和ArrayList<Integer>

        1ArrayList<E>整个称为泛型类型

        2ArrayList<E>中的E称为类型变量或类型参数

        3、整个ArrayList<Integer>称为参数化类型

        4ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数

        5ArrayList<Integer>中的<>称为typeof

        6ArrayList称为原始类型

       参数化:parametered,已经将参数变为实际类型的状态。

三、在使用java提供的对象时,什么时候写泛型?

        通常在集合框架中很常见,只要见到<>就要定义泛型。

        其实<>就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

四、关于参数化类型的几点说明:

1、参数化类型与原始类型的兼容性

        第一、参数化类型可引用一个原始类型的对象,编译只是报警告。

        如:Collection<String>coll = new Vector();

        第二、原始类型可引用一个参数化类型的对象,编译报告警告

        如:Collectioncoll = new Vector<String>();

        原来的方法接受一个集合参数,新类型也要能传进去。

2、参数的类型不考虑类型参数的继承关系:

        Vector<String> v = newVector<Objec>();//错误的

        不写Object没错,写了就是明知故犯

        Vector<Objec> v = newVector<String>();//错误的

3、编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型

        如:Vector<Integer>vectorList[] = new Vector<Integer>[10];//错误的

五、泛型类

1、若类实例对象中要使用到同一泛型参数,即这些地方引用类型要保持同一个实际类型时,这时候就要采用泛型类型的方式进行定义,也就是类级别的泛型。

2、什么时候定义泛型类

       当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。

3、泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所以要操作的类型就已经固定了。

4、类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方式都可以:

        GenericDao<String>dao = null;

        newgenericDao<String>();

5、语法格式:

       class Utils<XX>

        {

             private XX s;

             public void setxx(XX s)

             {

                 this.s=s;

             }

             public XX getXX()

             {

                  return s;

             }

        }

注意:

        1、在对泛型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。

        2、当一个变量被声明为参数时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态变量和静态方法调用,因为静态成员是被所有参数化的类共享的,所以静态成员不应该有类级别的类型参数。

六、泛型方法

        为了让不同方法可以操作不同类型,而且类型还不确定。那么可以将泛型定义在方法上。

特殊之处:

        静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

泛型方法的特点:

         1、位置:用于放置泛型的类型参数的<>应出现在方法的其他所有修饰符之后和在方法的返回类型之前,也就是紧邻返回值之前,按照惯例,类型参数通常用单个大写字母表示。

         2、只有引用类型才能作为泛型方法的实际参数。

         3、除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符。例如,Class.getAnnotation()方法的定义。并且可以用&来指定多个边界,如<V extends Serializable& cloneable> void method(){}。 

         4、普通方法、构造函数和静态方法中都可以使用泛型。

         5、可以用类型变量表示异常,称之为参数化的异常,可用于方法的throws列表中,但是不能用于catch子句中。

         6、在泛型中可同时有多个类型参数,在定义它们的<>中用逗号分开。例如:

               public static <K,V> V getValue(K key) { return map.get(key);}

       通配符方案要比泛型方法更有效,当一个类型变量用来表达两个参数之间或参数和返回值之间的关系时,即同一个类型变量在方法签名的两处被使用,或者类型变量在方法体代码中也被使用,而不是仅在签名的时候使用,才需要使用泛型方法。

小结:

对泛型的定义:

        第一、定义泛型:当又不确定的类型需要传入到集合中,需要定义泛型。

        第二、定义泛型类:如果类型确定后,所操作的方法都是属于此类型,则定义泛型类。

        第三、定义泛型方法:如果定义的方法确定了,里面所操作的类型不确定,则定义泛型方法。


二     System

一、概述

1System是描述系统一些信息的类,类中的属性和方法都是静态的。不能被实例化,没有提供构造函数。

2、两个部分:

       out:标准输出流。默认是控制台。

        in:标准输入流。默认是键盘。

二、方法

1、获取系统的属性信息:

        PropertiesgetProperties();

说明:

        1)此方法返回的双列集合,即键值对;因为PropertiesHahstable的子类,也就是Map集合的一个子类对象,那么通过Map方法取出该集合中的元素。

         2)该集合存储的都是字符串,没有泛型定义

2、获取指定属性信息:

        String getProperty(Stringkey);

3、在系统内定义特有信息:

        String setProperty(Stringkey,String value);

4、如何在jvm启动时,加载一些属性信息:

       通过命令:java -D<name>=<value>可以设置特有的系统属性信息

 

     Runtime

一、概述

        1、每个java应用程序都有一个Runtime类实例,使用应用程序能与其中运行的环境相连接,应用程序不能创建自己的Runtime类的实例,是由系统底层自己创建的。

        2、该类中并没有提供构造函数。说明不可以new对象。那么会直接想到该类中的方法都是静态的。查阅API文档发现,该类中还有非静态方法。说明该类肯定会提供了方法获取本来对象。而且该方法是静态的,并返回值类型是本来类型。

        3、由以上特点可以看出该类使用了单例设计模式完成。

二、方法

1、获取本类对象

        static RuntimegetRuntime();

2、在单独的进程中执行指定字符串命令

        Processexec(String command);

3、在Process中有一个杀掉子进程的方法,可将exec方法开启的进程结束

        void destroy();

 

四     时间类

一、Date

1、概述

        Date类表示特定的瞬间,精确到毫秒。

        java中的默认显示格式为:Mon Jun 10 22:35:21 CST2013

2、自定义格式

        默认的格式不一定满足每个人的需求,那么就需要自定义格式化模式。因为Date类中的大部分方法已过时,所以只能找其子类来实现。子类DateFormat中有format方法可以实现,但是DateFormat是抽象类,不能实例化。但是其下有个SimpleDateFormat子类,可以定义时间模式。

具体步骤:

        1)创建Date对象

        2)将时间模式封装到SimpleDateFormat对象中

        3)调用format方法让格式化模式指定Date对象
二、Carendar

1、概述:

        1Calendar是一个抽象类,它为特定瞬间与一组诸如YEARMONTHDAY_OF_MONTH等日历字段之间的转换提供了一些方法。

        2Calendar可以对年月日等时间进行获取。并提供了相应的子段值。可参阅API文档。

2、方法:

2.1、基本获取时间

        1)获取年份:Calendar.YEAR

        2)获取月份:Calendar.MONTH

        3)获取日期:Calendar.DAY_OF_MONTH

        4)获取星期:Calendar.DAY_OF_WEEK

        5)获取小时:Calendar.HOUR_OF_DAY

        6)获取分钟:Calendar.MINUTE

        7)获取秒数:Calendar.SECOND

2.2、设置时间:

        1)根据日历的规则,为给定的日历字段添加或减去指定的时间量:

                void add(int field,int amount);

        2)获取指定的日历字段对应的时间值:

                int get(int field);

        3)将给定日历字段对应的时间值设置为给定值:

                void set(int field,int value);

       设置日历字段 YEARMONTHDAY_OF_MONTH的值:

                void set(int year,int month,int date);

 

     Math

一、概述

        Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。该类全为静态方法。

二、方法

        1doubleceil(double d);//返回大于指定数据的最小整数

        2doublefloor(double d);//返回小于指定数据的最大整数

        3double pow(doublea,double b);//返回ab次方

        4long round(doubleb);//返回b四舍五入的值 

        5doublerandom();//返回正号的double值,是一个大于等于0.0且小于1.0的随机数

三、Random

        这是java.util中的一个单独的类,该类对象用于获取随机数。与Math中的random方法是一样的,不过这个类有自身的方法,可以将相应的随机数强转为指定基本数据类型。

        如:intnextInt(int n);//返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int值。