A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 贾成龙 中级黑马   /  2012-8-19 02:17  /  1760 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Test {
    public static void main(String[] args) {        
        invoke(null);
    }
    private static void invoke(Object obj) {
        System.out.println("Object");
    }
    private static void invoke(int[] nums) {
        System.out.println("Arrays");
    }
}


搞不清楚为什么是输出Arrays。以我的理解是Object!不知道为什么是Arrays?

3 个回复

倒序浏览
是方法重载的问题,   由编译器在编译时期进行方法选择,   一般会选择同类型或者最匹配的类型进行调用.   
null可以匹配任何对象,   上面两个方法都可以匹配,   这时编译器会选择更加特殊的(specific)那个,   这里就是int[] nums了,   Object是所有类的父类.子类都比父类更加匹配null!如果你再加上一个重载方法
  1.     private static void invoke(String nums) {
  2.         System.out.println("String");
  3.     }
复制代码
这时候编译期就会报错,编译器这时无法选择int[]还是String来进行匹配.
回复 使用道具 举报
java允许在一个类中,多个方法拥有相同的名字,但在名字相同的同时,必须有不同的参数,这就是重载,编译器会根据实际情况挑选出正确的方法,如果编译器找不到匹配的参数或者找出多个可能的匹配就会产生编译时错误,这个过程被称为重载的解析 1 普通方法的重载 普通方法的重载是Java实现多态技术的重要手段,为编程带来了很多便利当方法同名时,为了让编译器区别他们,至少需要下面之一不同 1 参数个数不同 2 对应位置上的参数类型不同不允许参数完全相同而只是返回值不同的情况出现。无法进行编译,程序在eclips中显示错误 2 构造方法的重载见文章构造方法的继承 重载的解析当类的设计者提供了重载方法之后,类的使用者在使用这些方法时编译器需要确定调用哪一个方法,确定的唯一依据是参数列表,确定的过程被称为重载的解析。编译器解析的步骤按照下面的顺序进行 1 根据调用的方法名,查找是否有定义好的同名方法,如果没有就会报错 2 比较形参和实参的数目是否相等,如果没有则会报错。如果有一个或多个方法符合条件,这些方法进入候选集 3 与候选集中的方法比较参数表,如果对应位置上的每个参数类型完全匹配,
当将名称分配到类、方法、变量时,使用能够容易理解的名称相当重要。例如,建立一个定义一个人的类,此时应该建立一个合适的名为Person的类。这一个类命名为一个随便的名称dkjfb也无可厚非,但对于开发这一软件的任何程序员是没有什么意义,因为它不能代表本身的含义。Person类应该具有以下的内容:
  class Person {
  private String firstName;
  private String lastName;
  }
  列举的代码声明了一个名为Person的类,其带有两个成员变量参数以存储姓和名。分配给成员变量参数的名称就符合它们本身的含义,这样就很容易地识别存储在变量中的内容。当调用一个Person类时,我们可以很直观地使用这些成员变量参数。

对象构建
  建立一个新的对象的实例会触发类的构造函数的方法。以下代码使用了一个基本的构造函数,这一构造函数无需接收任何变量:
  class Person {
  private String firstName;
  private String lastName;
  Person() {
  this.firstName = "";
  this.lastName = "";
  } }
  这一基本的构造函数使用空字符串的变量参数。在以后的程序中可以看到,在很多时候,对象建立时都附带已知的名字。你可以使用方法重载来建立多个方法,但每一个方法都有自己的方法记号。记号指定了被方法接受的参数。例如,这里是前一构造函数的方法记号:
  Person()
  这一方法可以重载以接收姓和名或者只是名:
  class Person {
  private String firstName;
  private String lastName;
  Person() {
  this.firstName = "";
  this.lastName = "";
  }
  Person(String lname) {
  this.firstName = "";
  this.lastName = lname;
  }
  Person(String fname, String lname) {
  this.firstName = fname;
  this.lastName = lname;
  } }
  在一个类中任何具有相同名称的两个方法必须有不同的参数类型或者不同的参数数目,否则编译器拒绝它们。现在类可以声明如下:
  Person p1 = new Person();
  Person p2 = new Person("Patton");
  Person p3 = new Person("Patton", "Tony");
  一个Java的特性
   
  重载能够用于标准的Java类中。System.out.println方法接收多参数列表。相关范例代码可以见以下:
  System.out.println("Builder.com");
  以及:
  int test = 2;
  System.out.println(test);
  这两个代码片段编译与执行时都没有任何错误。Println方法已经被设计为接收不同的变量,所以重载超乎构造函数的程序。为了更进一步的说明这一点,我们可以通过添加一个print方法来输出姓和名以加深我们的范例程序:
  class Person {
  private String firstName;
  private String lastName;
  Person() {
  this.firstName = "";
  this.lastName = "";
  }
  Person(String lname) {
  this.firstName = "";
  this.lastName = lname;
  }
  Person(String fname, String lname) {
  this.firstName = fname;
  this.lastName = lname;
  }
  public void Print() {
        System.out.println(firstName + " " + lastName);
  }
  
  public void Print(String pout) {
       System.out.println(pout + " " + firstName + " " + lastName);
  }
  }
  这两个print方法输出成员变量,其中一个方法接收文本而输出,而另一方法没有采用这样的方式。

当使用重载的时候
  重载是一个功能强大的特性,但你只能在需要的时候使用它。当你确实需要不同变量的多种方法,但这些方法都可以做相同的任务,此时就可以采用重载方式。也就是说,如果多种方法执行不同的任务,此时不能采用重载方式。否则,这一方法只能导致你的程序显得很混乱
回复 使用道具 举报
孔融让梨的故事听过吧?

就拿让梨这个典故来说

爸爸 跟 我 都是 人类 都可以吃梨 //首先排除不可能的

我 相对于 爸爸 而言是小辈 自然梨就落到我手里了 //优先权重问题 类似错误机制 都是从下往上 或者说从小到大的 在这里我再引申一点 Object是所有方法的基类 它的权重是最大的 编译器在进行编译的时候 都会优先选择权重小的先来 假如出错了就查看大的 假如大的也有问题或者没有大的 那就报错 (类似小孩做错事了 大人们出面解决) 大概就是这个意思 理解思想最重要

对于沙发那位朋友说的 就相当于现在突然出现了跟我同辈的 人
那么就会产生 “这梨应该给谁比较好呢?” 这样的问题 对于编译器来说 它是不能解决的 对它来说只有"true'or"false" 自然不能对不清不楚的问题进行思考 最终产生错误

理解思想 才能更好的学习
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马