java小心机(2)| 重载和构造器的小细节

阅读本文大概需要10分钟

java小心机,为你诉说java鲜为人知的一面

涉及基本数据类型的重载

基本类型能从一个"较小"的类型自动提升到"较大"的类型(扩展转换),此过程一旦牵涉到重载,可能就会造成一些混淆 看下以下例子,你是否清楚地知道答案?

import static java.lang.System.*;

public class PrimitiveOverLoading {
    public static void f1(char x){System.out.print("f1(char) ");};
    public static void f1(byte x){System.out.print("f1(byte) ");};
    public static void f1(short x){System.out.print("f1(short) ");};
    public static void f1(int x){System.out.print("f1(int) ");};
    public static void f1(long x){System.out.print("f1(long) ");};
    public static void f1(float x){System.out.print("f1(float) ");};
    public static void f1(double x){System.out.print("f1(double) ");};

    public static void f2(byte x){System.out.print("f2(byte) ");};
    public static void f2(short x){System.out.print("f2(short) ");};
    public static void f2(int x){System.out.print("f2(int) ");};
    public static void f2(long x){System.out.print("f2(long) ");};
    public static void f2(float x){System.out.print("f2(float) ");};
    public static void f2(double x){System.out.print("f2(double) ");};

    public static void f3(short x){System.out.print("f3(short) ");};
    public static void f3(int x){System.out.print("f3(int) ");};
    public static void f3(long x){System.out.print("f3(long) ");};
    public static void f3(float x){System.out.print("f3(float) ");};
    public static void f3(double x){System.out.print("f3(double) ");};

    public static void f4(int x){System.out.print("f4(int) ");};
    public static void f4(long x){System.out.print("f4(long) ");};
    public static void f4(float x){System.out.print("f4(float) ");};
    public static void f4(double x){System.out.print("f4(double) ");};

    public static void f5(long x){System.out.print("f5(long) ");};
    public static void f5(float x){System.out.print("f5(float) ");};
    public static void f5(double x){System.out.print("f5(double) ");};

    public static void f6(float x){System.out.print("f6(float) ");};
    public static void f6(double x){System.out.print("f6(double) ");};

    public static void f7(double x){System.out.print("f7(double) ");};

    void testConstVal(){
        out.print("5: ");
        f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);out.println();
    }

    void testDecimalVal(){
        out.print("5.2: ");
        f1(5.2);f2(5.2);f3(5.2);f4(5.2);f5(5.2);f6(5.2);f7(5.2);out.println();
    }

    void testChar(){
        char x = 'x';
        out.print("char: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }

    void testByte(){
        byte x = 0;
        out.print("byte: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }

    void testShort(){
        short x = 0;
        out.print("short: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }
    void testInt(){
        int x = 0;
        out.print("int: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }

    void testLong(){
        long x = 0;
        out.print("long: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }

    void testFloat(){
        float x = 0;
        out.print("float: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }
    void testDouble(){
        double x = 0;
        out.print("double: ");
        f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);out.println();
    }

    public static void main(String[] args){
        PrimitiveOverLoading p = new PrimitiveOverLoading();
        p.testConstVal();
        p.testDecimalVal();
        p.testChar();
        p.testByte();
        p.testShort();
        p.testInt();
        p.testLong();
        p.testFloat();
        p.testDouble();
    }
}

输出如下:

5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) 
5.2: f1(double) f2(double) f3(double) f4(double) f5(double) f6(double )f7(double) 
char: f1(char) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) 
byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) f6(float) f7(double) 
short: f1(short) f2(short) f3(short) f4(int) f5(long) f6(float) f7(double) 
int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) 
long: f1(long) f2(long) f3(long) f4(long) f5(long) f6(float) f7(double) 
float: f1(float) f2(float) f3(float) f4(float) f5(float) f6(float) f7(double) 
double: f1(double) f2(double) f3(double) f4(double) f5(double) f6(double) f7(double) 

可得出以下结论: 1.常数值5会被当做int值处理,常数值5.2会被当做double值处理 2.当传入的数据类型小于方法中声明的形参类型,实际数据就会被提升至最近的数据类型。 3.特例:对于char,如果无法恰好找到char参数的方法,且int参数方法存在时,char直接提升至int型

思考题:反过来,当传入的数据类型大于方法中声明的参数类型呢?(自行实践,相关阅读:java"小心机"(1)【资源彩蛋!】第4点类型转换

构造器中调用构造器

一个类中可能写了多个构造器,有时可能想在一个构造器中调用另一个构造器,以避免重复代码。构造器中调用构造器时,有几点细节需要注意,看下面例子: 注://! 为编译会报错的代码

public class Constructor {
    private String str;
    private int i;
    private float f;

    Constructor(String str){
        this.str = str;
    }

    Constructor(int i){
        this.i = i;
    }

    Constructor(String str,int i){
        //1.无法直接调用,需要使用this添加参数列表调用
        //! Constructor(str); 
        this(str);
        //2.只能调用一次构造器
        //! this(i); 
        this.i = i;
    }

    Constructor(String str,int i,float f){
         this.str = str;
         this.i = i;
         //3.只能在第一行调用构造器,否则编译不通过
         //! this(str); 
    }

    //普通方法
    void normalMethod(){
         //4.除构造器外,编译器禁止其他任何方法调用构造器
         //! this(str); 
    }
}

总结: 1.无法直接调用构造器,需要使用this添加参数列表调用 2.只能调用一次构造器 3.只能在构造器中第一行调用构造器,否则编译不通过 4.除构造器外,编译器禁止其他任何方法调用构造器

本文分享自微信公众号 - java从心(javaFollowHeart)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券