java 方法的重载_Java Challengers#1:JVM中的方法重载

欢迎来到新的Java Challengers博客!本博客致力于挑战Java编程中的概念。掌握它们,你将成为一名技术娴熟的Java程序员。

本博客中的技术需要付出一些努力才能掌握,但它们会对你作为Java开发人员的日常体验产生重大影响。当你知道如何正确应用核心Java编程技术时,避免错误会更容易,并且当你确切知道Java代码中发生的情况时,跟踪错误会更容易。

你准备好开始掌握Java编程中的核心概念了吗?然后让我们开始我们的第一个Java挑战!

术语:方法重载

由于重载,开发人员倾向于认为这种技术会使系统过载,但事实并非如此。在编程中,方法重载意味着使用相同的方法名和不同的参数。

什么是方法重载?

方法重载是一种编程技术,允许开发人员在同一个类中多次使用相同的方法名,但具有不同的参数。在这种情况下,我们说该方法是重载的。清单1显示了一个方法,其参数在数量,类型和顺序上有所不同。

清单1.三种类型的方法重载

Number of parameters:

public class Calculator {

void calculate(int number1, int number2) { }

void calculate(int number1, int number2, int number3) { }}

Type of parameters:

public class Calculator {

void calculate(int number1, int number2) { }

void calculate(double number1, double number2) { }

}

Order of parameters:

public class Calculator {

void calculate(double number1, int number2) { }

void calculate(int number1, double number2) { }

}

方法重载和原始类型

在清单1中,你可以看到基本类型int和double。我们将更多地使用这些和其他类型,所以花一点时间来回顾Java中的原始类型。

表1. Java中的原始类型

为什么我们要使用方法重载?

重载使你的代码更清晰,更易于阅读,它还可以帮助你避免程序中的错误。

与清单1相比,想象一个程序,其中有多个calculate()方法,其名称为calculate1 calculate2, calculate3. 。。不好,对吗?重载calculate()方法允许你使用相同的方法名称,同时仅更改需要更改的内容:参数。找到重载方法也很容易,因为它们在代码中组合在一起。

什么不是重载?

请注意,更改变量的名称不是重载。以下代码将无法编译:

public class Calculator {

void calculate(int firstNumber, int secondNumber){}

void calculate(int secondNumber, int thirdNumber){}

}

你也不能通过更改方法签名中的返回类型来重载方法。以下代码不会编译:

public class Calculator {

double calculate(int number1, int number2){return 0.0;}

long calculate(int number1, int number2){return 0;}

}

构造函数重载

你可以像对待方法一样重载构造函数:

public class Calculator {

private int number1;

private int number2;

public Calculator(int number1) {this.number1 = number1;}

public Calculator(int number1, int number2) {

this.number1 = number1;

this.number2 = number2;}

}

挑战方法重载!

你准备好迎接你的第一个Java挑战吗?我们来看看吧!

首先仔细查看以下代码。

清单2.高级方法重载挑战

public class AdvancedOverloadingChallenge3 {

static String x = "";

public static void main(String... doYourBest) {

executeAction(1);

executeAction(1.0);

executeAction(Double.valueOf("5"));

executeAction(1L);

System.out.println(x);

}

static void executeAction(int ... var) {x += "a"; }

static void executeAction(Integer var) {x += "b"; }

static void executeAction(Object var) {x += "c"; }

static void executeAction(short var) {x += "d"; }

static void executeAction(float var) {x += "e"; }

static void executeAction(double var) {x += "f"; }}

好的,你已经查看了代码。输出是什么?1.befe

2.bfce

3.efce

4.aecf

刚刚发生了什么?JVM如何编译重载方法

为了理解清单2中发生的事情,你需要了解有关JVM如何编译重载方法的一些信息。

首先,JVM是智能懒惰的:它总是尽可能少地执行一个方法。因此,当你考虑JVM如何处理重载时,请记住三种重要的编译器技术:1.宽化类型转换

2.box(自动装箱和拆箱)

3.可变参数

如果你从未遇到过这三种技术,那么一些示例应该有助于使它们清晰明了。请注意,JVM 按给定的顺序执行它们。

这是一个宽化的例子:

int primitiveIntNumber = 5;

double primitiveDoubleNumber = primitiveIntNumber ;

这是宽化时基本类型的顺序:图1.宽化时基本类型的顺序

以下是自动装箱的示例:

int primitiveIntNumber = 7;

Integer wrapperIntegerNumber = primitiveIntNumber;

注意编译此代码时幕后发生的事情:

Integer wrapperIntegerNumber = Integer.valueOf(primitiveIntNumber);

这是一个拆箱的例子 :

Integer wrapperIntegerNumber = 7;

int primitiveIntNumber= wrapperIntegerNumber;

以下是编译此代码时幕后发生的事情:

int primitiveIntNumber = wrapperIntegerNumber.intValue();

这是一个可变参数的例子; 请注意,可变参数它始终是最后执行的:

execute(int… numbers){}

什么是可变参数?

用于可变数量参数,可变参数基本上是由三个点指定的值数组(...)我们可以传递许多int我们想要给这个方法的数字。

例如:

execute(1,3,4,6,7,8,8,6,4,6,88...); // We could continue…

可变参数非常方便,因为值可以直接传递给方法。如果我们使用数组,我们必须使用值实例化数组。

宽化:一个实际的例子

当我们将数字1直接传递给executeAction方法时,JVM会自动将其视为一个int。这就是为什么这个数字不适用于该executeAction(short var)方法。

同样,如果我们传递数字1.0,JVM会自动将该数字识别为a double。

当然,数字1.0也可以是a float,但类型是预先定义的。这就是executeAction(double var)清单2中调用该方法的原因。

当我们使用Double包装器类型时,有两种可能性:包装器数字可以解包为基本类型,也可以宽化为Object。(请记住,Java中的每个类都继承了Object类。)在这种情况下,JVM选择将Double类型宽化为一个Object,因为它比取消装箱所需的工作量少,正如我之前所解释的那样。

我们传递的最后一个数字是1L,因为我们这次指定了变量类型,所以它是long。

重载常见错误

到目前为止,你可能已经发现方法重载会让事情变得棘手,所以让我们考虑一下你可能遇到的一些挑战。

使用包装器进行自动装箱

Java是一种

int primitiveIntNumber = 7;Double wrapperNumber = primitiveIntNumber;

自动装箱只适用于该double类型,因为编译此代码时发生的情况与以下内容相同:

Double number = Double.valueOf(primitiveIntNumber);

上面的代码将编译。第一种 int类型将被扩展为double,然后它将被包装成Double。但是当自动装箱时,没有类型宽化,函数Double.valueOf将收到一个double,而不是一个int。在这种情况下,自动装箱仅在我们强制转换时才有效,如下所示:

Double wrapperNumber = (double) primitiveIntNumber;

请记住, Integer不能转换为Long和Float不能转换为Double。没有继承关系。这些每个类型--Integer,Long,Float,和Double-- 是一个Number和Object。

如有疑问,请记住包装数字可以扩展为Number或Object。(还有很多关于包装的探索,但我会将它留给另一篇文章。)

JVM中的硬编码数字类型

当我们没有为数字指定类型时,JVM将为我们执行此操作。如果我们直接在代码中使用数字1,JVM将创建它作为int。如果你尝试将1直接传递给接收short的方法,则无法编译。

例如:

class Calculator {

public static void main(String… args) {

// This method invocation will not compile // Yes, 1 could be char, short, byte but the JVM creates it as an int calculate(1);

}

void calculate(short number) {}

}

使用数字1.0时将应用相同的规则; 虽然它可能是 float,但JVM会将此数字视为double:

class Calculator {

public static void main(String… args) {

// This method invocation will not compile // Yes, 1 could be float but the JVM creates it as double calculate(1.0);

}

void calculate(float number) {}

}

另一个常见错误是认为该Double包装类型或任何其他包装类型更适用于接收double的方法。事实上,对于JVM来说,将Double宽化到Object而不是将其拆箱为double类型花费的工作更少。

总而言之,当直接在Java代码中使用时,1将是int,1.0将是 double。宽化是最懒的执行路径,接下来是装箱或拆箱,最后的操作将始终是可变参数。

作为一个奇怪的事实,你知道这个char类型接受数字吗?

char anyChar = 127; // Yes, this is strange but it compiles

关于重载要记住什么

对于需要使用不同参数的相同方法名称的情况,重载是一种非常强大的技术。这是一种有用的技术,因为在代码中使用正确的名称会对可读性产生重大影响。你可以简单地重载它,而不是复制方法并为你的代码添加混乱。这样做可以使代码保持清洁,易于阅读,并降低了重复方法破坏系统某些部分的风险。

需要记住的是:当重载方法时,JVM将尽可能少地工作; 这是最懒惰的执行路径的顺序:l 首先是宽化

l 第二是装箱

l 第三是可变参数

需要注意的是:直接声明一个数字会产生棘手的情况:1将是int,而1.0将是 double。

还要记住,你可以使用语法显式声明这些类型,1F或1f用于float或者1D或1d用于 double。

这就是我们的第一个Java挑战,介绍了JVM在方法重载中的作用。重要的是要意识到JVM本质上是懒惰的,并且总是遵循最懒的执行路径。

答案

清单2中的Java Challenger的答案是:选项3. efce。

有关Java中方法重载的更多信息

·

·

·

公众号:银河系1号

联系邮箱:public@space-explore.com

(未经同意,请勿转载)

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值