java 方法参数多_java 方法参数过多,怎么处理?

本人对java的研究甚少,之前只是用一用,从未有过深度的学习,但却意外的发现了一个问题,那就是java的参数过多会出现错误,你们可能会认为,我找到的这个问题没有任何意义,对,我也是这样想的,可是,你们不妨来听我讲一讲,看看是否是这样的道理,若是不是,也请大神们提出错误,并给我一个合适的答案,让个人知识也可以有所提高,具体错误可见截图:

java

7435b297d07740c8bff2709b.html

7435b297d07740c8bff2709b.html

固然,这个错误不只使用javac进行编译的时候会报错,并且在eclipse中也会报错,错误内容一致,参数过多web

在这里我提出了如下几个问题:编程

1.java的方法到底支持多少个参数?windows

2.java存在这样的问题该怎么解决?安全

答:eclipse

1.本人使用的环境以下:编程语言

jdk1.6 + windows7 旗舰版ide

通过个人测试,我发现java的方法参数在超过254个时便会报错函数

2.在这里我引用 一个名叫 王村平 的文章来处理此类问题:性能

我认为构造函数和方法过长的传递参数列表是一种红色警告(”red flag“)。在开发过程当中,从逻辑的和功能的角度来看并不是错误,可是一般意味着如今或者未来犯错误的可能性更高。经过阅读一系列文章,我发现一些解决参数列表过长的办法,或者至少这些办法能够减小参数个数、加强代码的可读性并下降发生错误的几率。任何解决问题的办法都具备优势和缺点。本文旨在经过使用自定义类型改进长参数方法和构造函数代码的可读性和安全性。

方法和构造函数的参数列表过长会产生一系列的障碍。大量的参数不只使得代码看起来冗余,并且使得调用起来会很困难。同时,它又容易致使因疏忽而产生的参数移位(参数类型没变,可是由于位置改变值却改变了)。这些错误在特定状况下难以发现。幸运地是大多时候咱们没必要处理另外一个参数过长的缺点:Java虚拟机(JVM)经过编译时报告错误(compile-time error)限制了方法的参数数量。

使用自定义类型一方面能够减小构造函数和方法的传参个数,另外一方面又能够加强参数列表的可读性而且下降参数位置放错的可能性。自定义类型的实现方式包括Data Transfer Objects、JavaBeans、Value Objects、Reference Objects或者其余(在Java中经典的实现方式:类和枚举)自定义类型。

下面来看一个例子,该方法包含多个String和boolean类型参数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

/**

* Instantiate a Person object.

*

* @param  lastName

* @param  firstName

* @param  middleName

* @param  salutation

* @param  suffix

* @param streetAddress

* @param city

* @param state

* @param isFemale

* @param isEmployed

* @param isHomeOwner

* @return

*/

public Person createPerson(

final String lastName,

final String firstName,

final String middleName,

final String salutation,

final String suffix,

final String streetAddress,

final String city,

final String state,

final boolean isFemale,

final boolean isEmployed,

final boolean isHomeOwner)

{

// implementation goes here

}

能够发现很容易搞混参数的顺序,而后把它们放错位置。我一般更乐意经过改变参数类型来作一些提升,以期减小参数个数。下面这些代码展现了如何使用自定义类型。

三个名字能够改成自定义类型Name,而不是使用String。

Name.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package dustin.examples;

/**

* Name representation.

*

* @author Dustin

*/

public final class Name

{

private final String name;

public Name(final String newName)

{

this.name = newName;

}

public String getName()

{

return this.name;

}

@Override

public String toString()

{

return this.name;

}

}

称呼和后缀也能够替换为以下两段代码所示的自定义类型:

Salutation.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

package dustin.examples;

/**

* Salutations for individuals' names.

*

* @author Dustin

*/

public enum Salutation

{

DR,

MADAM,

MISS,

MR,

MRS,

MS,

SIR

}

Suffix.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package dustin.examples;

/**

* Suffix representation.

*

* @author Dustin

*/

public enum Suffix

{

III,

IV,

JR,

SR

}

其余的代码也可以使用自定义类型。下面经过枚举的方式替换boolean型,以提升代码的可读性:

Gender.java

1

2

3

4

5

6

7

8

9

10

11

12

package dustin.examples;

/**

* Gender representation.

*

* @author Dustin

*/

public enum Gender

{

FEMALE,

MALE

}

EmploymentStatus.java

1

2

3

4

5

6

7

8

9

10

11

12

package dustin.examples;

/**

* Representation of employment status.

*

* @author Dustin

*/

public enum EmploymentStatus

{

EMPLOYED,

NOT_EMPLOYED

}

HomeOwnerStatus.java

1

2

3

4

5

6

7

8

9

10

11

12

package dustin.examples;

/**

* Representation of homeowner status.

*

* @author Dustin

*/

public enum HomeownerStatus

{

HOME_OWNER,

RENTER

}

此人的地址信息能够经过以下代码所示的自定义类型做为参数进行传递。

StreetAddress.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package dustin.examples;

/**

* Street Address representation.

*

* @author Dustin

*/

public final class StreetAddress

{

private final String address;

public StreetAddress(final String newStreetAddress)

{

this.address = newStreetAddress;

}

public String getAddress()

{

return this.address;

}

@Override

public String toString()

{

return this.address;

}

}

City.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package dustin.examples;

/**

* City representation.

*

* @author Dustin

*/

public final class City

{

private final String cityName;

public City(final String newCityName)

{

this.cityName = newCityName;

}

public String getCityName()

{

return this.cityName;

}

@Override

public String toString()

{

return this.cityName;

}

}

State.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

package dustin.examples;

/**

* Simple representation of a state in the United States.

*

* @author Dustin

*/

public enum State

{

AK,

AL,

AR,

AZ,

CA,

CO,

CT,

DE,

FL,

GA,

HI,

IA,

ID,

IL,

IN,

KS,

KY,

LA,

MA,

MD,

ME,

MI,

MN,

MO,

MS,

MT,

NC,

ND,

NE,

NH,

NJ,

NM,

NV,

NY,

OH,

OK,

OR,

PA,

RI,

SC,

SD,

TN,

TX,

UT,

VA,

VT,

WA,

WI,

WV,

WY

}

经过使用自定义类型,开始展现的方法的代码变得更加易读易懂,同时更不容易出错了。下面是使用自定义类型改写后的方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

public Person createPerson(

final Name lastName,

final Name firstName,

final Name middleName,

final Salutation salutation,

final Suffix suffix,

final StreetAddress address,

final City city,

final State state,

final Gender gender,

final EmploymentStatus employment,

final HomeownerStatus homeowner)

{

// implementation goes here

}

在上面这段代码中,编译器会不容许使用先前那种不少String、boolean参数的方式。这样来减小了放错参数顺序的可能性,从而帮助到开发者。可是三个名字仍然存在一个潜在的问题,由于代码的调用者依然容易搞乱它们的顺序。出于这种担忧,须要为此专门定义FirstName、LastName、MiddleName 三种类型。但一般我喜欢使用一个自定义类型,里面放置上述三个名字做为新类的属性。固然那属于后来即将讲解的解决Java参数过长问题的文章的内容了。

使用自定义类型的好处和优势

提升了代码的可读性,为代码的维护者和API调用者提供了便利。提升了在编写代码时开发环境(IDE)参数匹配的能力,没有什么比使用自定义类型的编译环境检查更能帮助开发环境的了。一般来讲,我更喜欢尽量地把这些自动检查由运行环境移到编译环境,而且把他们定义为可直接调用的静态类型而非普通类型。

进一步说,自定义类型的存在也使咱们未来为它添加更多细节变得更加容易。例如:未来我也许会为方法建立人添加一个全名或者把其余的状态放在枚举器当中,同时这样也不会改变自定义类型的原有面貌。这些都是使用String类型没法完成的。这样作的另外一个潜在优势就是使用自定义类型拥有更大的灵活性,能够在不改变原有类型面貌的状况下改变实现方式。这些自定义类型(不包括枚举器)可以被扩展(String则不具有),而且能够在不改变它的类型的状况下灵活添加自定义细节。

自定义类型的代价和缺点

广泛存在缺点之一,就是开始须要额外的实例化和占用内存。例如:Name类须要实例化,并且封装了String。我认为之因此有人会持有这种观点,更多的是由于他从一种尚不够成熟的所谓的最优化角度,而非实用合理的角度来衡量性能问题。固然也有这种状况存在,即:额外实例化这些类型花费了太多的代价而且不能证实加强可读性和编译能力所带来的好处。然而大多时候这种额外的开销都是能够承受的,不会产生什么可见的坏影响。若是大多数时候使用自定义类型而不用String或者boolean会产生性能问题,这真的让人难以置信。

另外一些人认为使用自定义类型而非内置类型须要付出额外的写和测试代码的努力。然而,正如个人这篇文章的代码所显示的那样,这些很是简单的类和枚举器写和测试起来并不难。使用一个优秀的开发环境和一门灵活的编程语言(如:Groovy),编写和测试会更加容易并且一般能够自动完成。

结论

我喜欢使用自定义类型来提升代码的可读性,将更多的编译检查负担转给编译器。我不喜欢这种传参方式的最大缘由在于:这种方法自己只是提升了拥有过长参数列表的构造函数和方法的可读性却并无减小实际须要传递的参数数量,代码的调用者依然须要写那些笨拙的客户端代码来调用构造函数和方法。所以,我一般使用其它技术而不是增长自定义类型来解决向方法传递参数过长的问题。这些技术将在接下来的文章里讲述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值