方法签名

方法名是驼峰命名

方法名最好能说明该方法主要做什么

方法参数的名字最好能说明该参数的意义

方法参数个数最好低于6个

例如:

public void setTitleVisible(int length, String title, boolean visible ) {
//some implementation here
}

java5引入了相同类型的可变参数(不定项参数)

例如:

public void find(String ... elements) {
//some implementation here
}

在内部,java编译器将可变参数转化为数组

java5也允许可变参数为泛型,但是参数的类型不可知,java编译器为了确保参数被合理使用,建议方法声明为final,并且用@SafeVarargs注解。

例如:

@SafeVarargs
final public<T> void find(T ... elements) {
//some implementation here
}

另外一种方法

@SuppressWarnings("unchecked")
public<T> void findSuppressed(T ... elements) {
//some implementation here
}

下面展示方法签名中checked exceptions的使用,但是最近几年证实,它并没有如期望那样使用。

public void write(File file) throws IOException {
//some implementation here
}

最好标记方法参数为final,还有这种类型的方法参数可以被匿名方法访问。

方法体

最重要的一个原则:一个方法最好只实现一个功能

另一个原则:方法实现体最好比较短,一个屏幕一定要能看完

在方法体中,最好减少return语句的数量。建议仅仅只有一个return语句

方法重载

public String numberToString(Long number) {
return Long.toString(number);
}
public String numberToString(BigDecimal number) {
return number.toString();
}

方法重载有点像泛型,但是泛型有一些地方工作不太好的地方,方法重载可以很好的工作。

泛型和方法重载结合可以变得很强大,但是在java中并不经常使用。

例如:

public<T extends Number> String numberToString(T number) {
return number.toString();
} public String numberToString(BigDecimal number) {
return number.toPlainString();
}

方法重写

public class Parent {
public Object toObject(Number number) {
return number.toString();
}
} public class Child extends Parent {
@Override
public String toObject(Number number) {
return number.toString();
}
}

在子类中返回参数被改变啦,但是编译器是可以通过的。但是子类返回的参数类型必须是父类返回的参数类型的子类。

现在我们添加一个方法:

public class Child extends Parent {
public String toObject(Double number) {
return number.toString();
}
}

方法签名中(Double代替Number),但是在这种情况下,这是方法重载,并不是方法重写。

递归

例如:

public int sum(int[] numbers) {
if (numbers.length == 0) {
return 0;
} else if (numbers.length == 1) {
return numbers[0];
} else {
return numbers[0] + sum(Arrays.copyOfRange(numbers, 1,
numbers.length));
}
}

上诉方法并不是有效的实现方法,但是却很好的展示了递归。

递归存在这一个著名的问题,这个问题依赖于调用链有多深,这样会放大栈,引起StackOverflowError异常,但是事情并不总是那么坏,有一种技术可以避免stack overflows,叫做tail call optimization。如果方法是tail-recursive方法,那么这种技术会被应用。

例如:

public int sum(int initial, int[] numbers) {
if (numbers.length == 0) {
return initial;
} else if (numbers.length == 1) {
return initial + numbers[0];
} else {
return sum(initial + numbers[0],
Arrays.copyOfRange(numbers, 1, numbers.lenght));
}
}

不幸的是,现在java编译器(还有JVM JIT编译器)并不支持tail call optimization,但是仍然需要了解这种技术,当在java中写递归的时候,需要考虑。

文档方法

方法参数和返回值

文档化你的方法是很好的形式,但是并不能阻止用户输入错误的方法参数,所以,所有的公共方法都需要进行参数的验证,并不能相信用户总是输入正确的数据。

例如:

public int parse(String str) throws NumberFormatException {
if (null == str) {
throw new IllegalArgumentException("String should not be null");
} return Integer.parseInt(str);
}

在java8之前,在方法调用中,如果本次调用没有返回值,则返回null,这就是为什么Java会经常抛出NullPointerException异常,Java8使用Option<T>解决该问题。

方法作为API注意事项

使用有意义的方法名和方法参数

保持方法参数个数低于6

保持你的方法少,具有可读性

总是文档化你的公共方法,包括先决条件,例子

总是进行参数验证和sanity check

最好不要返回null值

不管什么时候,尝试涉及不变的方法

Java设计和实现方法的更多相关文章

  1. 《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)

    1.简介 上一篇宏哥介绍了如何设计支持不同浏览器测试,宏哥的方法就是通过来切换配置文件设置的浏览器名称的值,来确定启动什么浏览器进行脚本测试.宏哥将这个叫做浏览器引擎类.这个类负责获取浏览器类型和启动 ...

  2. java设计模式之工厂方法探究

    简单工厂 + 工厂方法 + 抽象工厂       看了十几篇博客,每篇基本上都能有个自己的解释,我汇总这些内容,重新梳理整理了一番,以形成自己的理解.       简单工厂模式其实不算23种设计模式之 ...

  3. 浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  4. atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug

    atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&qu ...

  5. 【转】浅谈Java中的hashcode方法(这个demo可以多看看)

    浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...

  6. java设计原则:16种原则

    一   类的设计原则   1 依赖倒置原则-Dependency Inversion Principle (DIP) 2 里氏替换原则-Liskov Substitution Principle (L ...

  7. java :equals()和hashcode()方法的结合使用

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  8. Java中的大小写字母相互转换(不利用Java自带的方法)

    Java中的大小写字母相互转换(不利用Java自带的方法) 1.设计源码 /** * * @title:UpperAndLower.java * @Package:com.you.utils * @D ...

  9. 如何重写Java中的equals方法

    Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型, ...

随机推荐

  1. 51驱动LCD1602

    1602 采用标准的 16 脚接口,其中: 第 1 脚:VSS 为地电源 第 2 脚:VDD 接 5V 正电源 第 3 脚:V0 为液晶显示器对比度调整端,接正电源时对比度最弱,接地 电源时对比度最高 ...

  2. Java使用POI实现数据导出excel报表

    Java使用POI实现数据导出excel报表 在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅 ...

  3. [MySQL]mysql指定路径启动

    /usr/sbin/mysqld --defaults-file=/etc/mysql/my.cnf --basedir=/usr --datadir=/var/lib/mysql --pid-fil ...

  4. NSString总结

    [from]http://www.jianshu.com/p/7994b0ad6b88 问题:NSString到底是不是字符串? NSString 是 OC中专门处理字符串的对象!提供了转换大小写,拼 ...

  5. APK的反编译

    有秘密的地方就有见不得光的东西,我讨厌这些,所以对于某一个XX圈APP极其反感,感觉就像一个色情网站 一.ApkTool的使用 看了几个教程,自己下载的好像总是不完整,下载包解压后一个没有aapt.e ...

  6. iOS UITabBar

    参考文章:http://www.cnblogs.com/wendingding/p/3775488.html 简单明了,不用再总结了.

  7. UVa 10405 & POJ 1458 Longest Common Subsequence

    求最长公共子序列LCS,用动态规划求解. UVa的字符串可能含有空格,开始用scanf("%s", s);就WA了一次...那就用gets吧,怪不得要一行放一个字符串呢. (本来想 ...

  8. MariaDB10自动化安装部署

    去MariaDB官网下载MariaDB本文用的是MariaDB 10.1.16 https://downloads.mariadb.org 选择二进制版本,下载到/root目录下 mariadb-10 ...

  9. 扩展BaseAdapter实现不存储列表项的ListView

    下面的实例将会通过扩展BaseAdapter来实现Adapter,扩展BaseAdapter可以取得对Adapter最大的控制权:程序要创建多个列表项,每个列表项的组件都由开发者来决定. 下面的布局文 ...

  10. Servlet RequestDispatcher需要注意的情况

    Servlet RequestDispatcher需要注意的情况: 如果使用getServletContext().getRequestDispatcher("/a.do")得到R ...