美文网首页
Object超类、 泛型、可变参数、对象包装器与自动打包、枚举类

Object超类、 泛型、可变参数、对象包装器与自动打包、枚举类

作者: Binary_r | 来源:发表于2019-03-23 14:11 被阅读0次

一、Object

Obje类是所有Java类的祖先。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
在不明确给出超类的情况下,sun定义的那么多类的终极父类是Object。Object描述的是所有类的通用属性与方法。

1、toString方法
public class Dome1 {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println("toString:" + o);//toString:java.lang.Object@15db9742
        System.out.println(o);//java.lang.Object@15db9742
    }
}

toString() 返回对象的描述信息 java.lang.Object@15db9742 类名@哈希码值的十六进制形式。
直接输入一个对象的时候,会调用对象的toString方法。

2、equals方法

equals() 返回的是比较的结果 如果相等返回true,否则false,比较的是对象的内存地址值。

public class Dome1 {

    public static void main(String[] args) {
        Object o = new Object();
        Object o1 = new Object();
        System.out.println(o.equals(o1));//false
        
        Object o2 = o;
        System.out.println(o.equals(o2));//true
    }

}
3、hashCode方法

hashCode() 返回该对象的哈希码值: 采用操作系统底层实现的哈希算法。 同一个对象的哈希码值是唯一的。
java规定如果两个对象equals返回true,那么这两个对象的hashCode码必须一致。

二、 泛型

1、泛型的产生

虽然可以再类型转换的时候通过if语句进行类型检查(instanceof),但是效率较低.(例如吃饭的时候,还需要判断米饭里有没有沙子,吃饭效率低).可以通过给容器加限定的形式规定容器只能存储一种类型的对象.
就像给容器贴标签说明该容器中只能存储什么样类型的对象。
所以在jdk5.0后出现了泛型。

2、泛型应用:

格式:集合类<类类型> 变量名 = new 集合类<类类型>();

public class Demo5 {
    public static void main(String[] args) {
        // 使用泛型后,规定该集合只能放羊,老虎就进不来了.
        ArrayList<Sheep> arr = new ArrayList<Sheep>();
        arr.add(new Sheep("美羊羊"));
        arr.add(new Sheep("懒洋洋"));
        arr.add(new Sheep("喜羊羊"));
        // 编译失败
        // arr.add(new Tiger("东北虎"));
        System.out.println(arr);
        Iterator<Sheep> it = arr.iterator();
        while (it.hasNext()) {
            // 使用泛型后,不需要强制类型转换了
            Sheep next = it.next();
            next.eat();
        }
    }
}

通过<> 来指定容器中元素的类型.
什么时候使用泛型:当类中操作的引用数据类型不确定的时候,就可以使用泛型类.

细节一:声明好泛型类型之后,集合中只能存放特定类型元素
public class Demo6 {
    public static void main(String[] args) {
        //创建一个存储字符串的list
        ArrayList<String> arr=new ArrayList<String>();
        arr.add("gz");
        arr.add("itcast");
        //存储非字符串编译报错.
        arr.add(1);
    }
}
细节二:泛型类型必须是引用类型
    public static void main(String[] args) {
        // 泛型类型必须是引用类型,也就是说集合不能存储基本数据类型
        // ArrayList<int> arr2=new ArrayList<int>();

        // 使用基本数据类型的包装类
        ArrayList<Integer> arr2 = new ArrayList<Integer>(); 
    }
}
细节三: 使用泛型后取出元素不需要类型转换.
public class Demo6 {
    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<String>();
        arr.add("gzitcast");
        arr.add("cditcast");
        arr.add("bjitcast");
        //使用泛型后取出元素不需要类型转换.
        String str=arr.get(0);
        System.out.println();
    }
}
3、泛型方法

函数上的泛型定义

      当函数中使用了一个不明确的数据类型,那么在函数上就可以进行泛型的定义。

      public <泛型的声明> 返回值类型  函数名( 泛型 变量名  ){   }
public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5 };
    
        new Demo6().getData(5);
    }
    public <T> T getData(T data) {
        return data;
    }
细节:

使用泛型方法前需要进行泛型声明,使用一对尖括号 <泛型>,声明的位置在static后返回值类型前。
当一个类中有多个函数声明了泛型,那么该泛型的声明可以声明在类上。

4、泛型类

格式:修饰符 class 类名<泛型>{
}

import java.util.Arrays;

public class Demo6<T> {
    public static void main(String[] args) {
        // 使用泛型类,创建对象的时候需要指定具体的类型
        new Demo6<Integer>().getData(5);
    }

    public T getData(T data) {
        return data;
    }
注意:静态方法不可以使用类中定义的泛型

因为类中的泛型需要在对象初始化时指定具体的类型,而静态优先于对象存在。那么类中的静态方法就需要单独进行泛型声明,声明泛型一定要写在static后,返回值类型之前.

泛型类细节:

1、创建对象的时候要指定泛型的具体类型
2、创建对象时可以不指定泛型的具体类型(和创建集合对象一眼)。默认是Object,例如我们使用集合存储元素的时候没有使用泛型就是那么参数的类型就是Object
3、类上面声明的泛型只能应用于非静态成员函数,如果静态函数需要使用泛型,那么
需要在函数上独立声明。
4、如果建立对象后指定了泛型的具体类型,那么该对象操作方法时,这些方法只能操作一种数据类型。
5、所以既可以在类上的泛型声明,也可以在同时在该类的方法中声明泛型。

三、可变参数

JDK中具有可变参数的类Arrays.asList()方法。
分别传多个参、传数组,传数组又传参的情况。
注意:传入基本数据类型数组的问题。
从JDK 5开始, Java 允许为方法定义长度可变的参数。
语法:数据类型…变量名。
可变长参数是Object[] 数组。(可变参数里存的是对象数组)
JDK中的典型应用:
Arrays.asList(T…a)是jdk中的典型应用。

需求:对若干个整数进行求和
使用数组接收整数
public static int sum1(int[] numbers) {
        if (numbers == null) {
            return 0;
        }

        if (numbers.length == 0) {
            return 0;
        }

        int sum = 0;
        for (int num : numbers) {
            sum += num;
        }
        return sum;
    }
可以使用可变参数
public static int sum2(int... numbers) {
        if (numbers == null) {
            System.out.println("可变参数的值为null");
            return 0;
        }

        if (numbers.length == 0) {
            System.out.println("可变参数的值的长度为0");
            return 0;
        }

        int sum = 0;
        for (int num : numbers) {
            sum += num;
        }
        return sum;
    }
可变参数的使用
public static void main(String[] args) {
        // int result = sum1(new int[] { 1, 3, 5, 7, 9 });
        // System.out.println(result);

        // // 使用了可变参数,传一个数组进去
        // int result = sum2(new int[] { 1, 3, 5, 7, 9 });
        // System.out.println(result);

        // 使用了可变参数,不必声明数组,简化书写
        // int result = sum2(2, 4, 6, 8, 10);
        // int result = sum2(1);
        int result = sum2();
        System.out.println(result);
    }
可变参数的细节

1、声明:
在一个方法中,最多只能有一个可变参数。可变参数只能放在参数列表的最后面。
2、调用:
当使用可变参数时,可以传0或多个参数。当使用可变参数时,也可以传一个数组进去,就表示多个参数。
3、使用:
在方法内部使用时,就是在使用一个数组。当调用时没有传参数时(传了0个),这时在方法内部的参数数组是有值的(不为null),但长度为0.

四、对象包装器与自动打包

对象包装器和自动装箱
有时,需要将int这样的类型转化为对象。所有的基本类型都有一个与之对应的类。例如,Integer类对应基本类型int。通常,这些类称为包装器(wrapper)。这些对象包装器拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character、Void和Boolean(前6个类派生于公共的超类Number)。对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时,对象包装器还是final,因此不能定义它们的子类。
例如:
ArrayList<Integer> list = new ArrayList<>();
下面这个调用:
list.add(3);
将自动地变成:
list.add(Integer.valueOf(3));
这种变换被称为自动装箱。
相反地,当将一个Integer类型对象赋值给一个int值时,将会自动拆箱。也就是说,编译器将下列语句:
int n = list.get(i);
翻译成:
int n = list.get(i).intValue();

五、枚举类

一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。
例如: 交通灯(红、黄、绿) 性别(男、女) 星期(星期一、二、三…..)
分数等级(A、B、C、D、E)
JDK 5新增的 enum 关键字用于定义一个枚举类。

每一个枚举值都是枚举类的具体实例对象.只不过是静态常量.

枚举类具有如下特性:

1、枚举类也是一种特殊形式的Java类。
2、枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
3、与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数.

public class Demo1 {
    public static void main(String[] args) {
        Gender male = Gender.MALE;
        System.out.println(male.getInfo());
    }
}

enum Gender {
    MALE("男"), FEMALE;

    // 成员变量
    private String info;

    // 构造函数
    private Gender() {

    }
    private Gender(String info) {
        this.info = info;
    }

    // 成员方法
    public String getInfo() {
        return info;
    }
}
枚举类也可以实现接口(序列化)、或继承抽象类。

JDK5中扩展了swith语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型(enum)。

public class Demo2 {
    public static void main(String[] args) {
        WeekDay mon = WeekDay.MON;
        switch (mon) {
        case MON:
            System.out.println("星期一要上班...");
            break;
        case TUE:
            System.out.println("星期二,继续上班...");
            break;
        }
    }
}

enum WeekDay {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}

相关文章

网友评论

      本文标题:Object超类、 泛型、可变参数、对象包装器与自动打包、枚举类

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