Java——类谜题

1、令人混淆的构造器

  代码如下格式:

public class Confusing {
    private Confusing(Object o) {
        System.out.println("Object");
    }
    private Confusing(double[] dArray) {
        System.out.println("double array");
    }
    public static void main(String[] args) {
        new Confusing(null);
    }
}

  分析:null这个参数,两个构造器都可以接受,会怀疑这段代码是否会通过编译,运行后发现可以通过编译并且打印出double array?Why?

  正解:知识点——Java重载解析过程是以两个阶段运行的。第一个阶段,选取所有可以获得并且可以使用的方法或构造器。第二阶段,从上一阶段选取的方法或构造器中选取一个最精准的方法。精准的理解——能接受的参数类型越少越精准。例如:本例中的Object,他接收的范围太广了,至少能够把double数组和int数组接受了,所以他就不精准。但是,能接收double数组但不能接收其他数据对象类型例如int,所以就相对来说显得更精准,所以在第二个阶段,选取了相对精准的方法,所以才会有了double的输出。

2、静态方法的覆盖

代码:

class Dog {
    public static void bark() {
        System.out.print("woof ");
    }
}

class Basenji extends Dog {
    public static void bark() { }
}

public class Bark {
    public static void main(String args[]) {
        Dog woofer = new Dog();
        Dog nipper = new Basenji();
        woofer.bark();
        nipper.bark();
    }
}

  先来说明一件事情:nipper编译期类型为Dog类型,运行期类型为Basenji类型。

  分析:静态方法的调用是在编译期选好的,而这个调用当然就要看对象的编译期类型。本例子中,woofer和nipper具有相同的编译类型Dog,虽然nipper在运行期间类型为Basenji,所以他们两个都会打印出woof即打印结果为:woof  woof。

  静态方法的覆盖叫隐藏,一般方法的覆盖叫重载。重载能够得到动态分配的特性(其实就是看运行期的对象类型),隐藏不能得到这种特性(隐藏只能看编译期类型)。所以,如果将Dog和Basenji中的函数方法去掉static,变为重载,那么将会只打印一个woof。

时间: 2024-10-13 07:17:26

Java——类谜题的相关文章

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个

Java类的定义及其实例化

如果你不了解类和对象的概念,请猛击这里:Java类和对象的概念 类必须先定义才能使用.类是创建对象的模板,创建对象也叫类的实例化. 下面通过一个简单的例子来理解Java中类的定义: public class Dog{ String name; int age; void bark(){  // 汪汪叫 System.out.println("汪汪,不要过来"); } void hungry(){  // 饥饿 System.out.println("主人,我饿了")

js原型对象与Java类的区别

在我学习Javascript的原型对象时,我总是不自觉地拿Java的类思想来做比较,时间久了,我渐渐认识到二者有巨大的不同. 首先,类是不能直接当方法来运行,它最简便的方式是调用其静态方法:而原型对象本身就是一个方法体,它可以直接运行.二者在构造对象的过程中,js可以扮演两种角色,一个可以将原型对象当方法来使用,才接触js时,都是以这种形式来使用,即万物皆方法体,像c;另一个是模仿面向对象的特性,为原型对象定义属性,运用构造器时,将构造器构造的对象的指针指通过原型链指向原型对象的属性,从而实现面

Java类的设计----Object 类

Object类 Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 public class Person { ... } 等价于: public class Person extends Object {. ... }例: method(Object obj){-}//可以接收任何类作为其参数 Object o=new Person; method(o); ==操作符与equals方法 ==操作符与equals方法的区别: =

java类的生命周期

类的生命周期:加载.连接(验证.准备.解析).初始化.使用.卸载主动引用(有且只有)初始化: 1.new.getstatic.putstatic.invokestatic如果类没初始化,则初始化new关键字实例化对象.读取或设置一个类的静态字段(被final修饰.*已在编译期把结果放入常量池的静态字段除外).调用一个类的静态方法  2.使用java.lang.reflect包的方法对类进行发射调用的时候,如果类没有进行过初始化,则初始化 3.当初始化一个类的时候,父类没初始化,则初始化 4.当虚

Java —类和对象

类和对象 类是对象的类型,是具有相同的属性和方法的一组对象的集合. 定义类 访问修饰符 class 类名 { 数据类型 属性名: 访问修饰符 返回值类型 方法名 {} } 创建对象:类名 对象名 = new 类名(); 使用对象:引用对象的属性:对象名.属性名;引用对象的方法:对象名.方法名(); 可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立. 成员变量和局部变量 成员变量:在类中定义,描述对象将要有什么.可以在本类的方法或其他类的方法中使用.java会给成员变量一个初始

Eclipse或MyEclipse没有在java类文件上显示Spring图标的问题

Eclipse或MyEclipse没有在java类文件上显示接口图标的问题解决办法: 前: 后:

Java类的生命周期详解

引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,文中有说的不对的地方,也希望各路高手前来指正. 首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区域,这几

jsp页面应用Java类

两种方法将Java类应用到jsp页面中: 1. <jsp:useBean id="类实例名字" class="具体的类" scope="page/request/session/application" /><jsp:setProperty name="id的值" property="参数名" value="参数值" />//或者多个参数直对<jsp:get