英文原文:Why Java Is a Purely Object-Oriented Language Or Why Not

Java是否确实是 “纯面向对象”?让我们深入到Java的世界,试图来证实它。

在我刚开始学习Java的前面几年,我从书本里知道了Java是遵循“面向对象编程范式(Object Oriented Programming paradigm)”的。在Java世界内一切都是对象,甚至包括字符串(String)这些都是对象(在 C 语言中,字符串是字符数组),那时候,我认为Java是一种面向对象的语言。

但是在后来,我在网上陆续看到不少开发者说“Java实际上不是纯粹的面向对象,因为并不是所有的东西在Java世界都是一个对象”。他们很多的论点都可以概括为以下两点:

所有的静态内容(static关键字修饰的变量和方法)不属于任何对象,这些是非对象的东西。

所有基本类型(char,boolean,byte,short,int,long,float,double)都不是对象,因

为我们不能做类似对象的所具有的操作(例如:使用“.”来访问对象的属性和方法)。

在那时,由于个人知识经验储备有限,我又很容地相信上面的论点,并且也开始认为 “Java 不是纯粹的面向对象编程语言”。

到了更后来,我发现JVM在创建对象的时候,实际上会创建两个对象:

一个是实例对象。

另一个是Class对象。该Class对象在JVM内仅仅会装载一次,该类的静态方法和静态属性也一同装载,JVM使用该Class对象来创建具体的实例对象(如上面的对象)。

例如,在下面的 Java 语句中,将有两个对象被创建:

Employee emp = new Employee ();

一个是实例对象 emp ;另一个则是Class对象,我们可以通过Employee.class引用到它;这个Class对象拥有所有的这个类定义的静态变量和静态方法。同时,如果我们访问通过emp对象来访问静态内容,会发现它其实指向的对象就是Employee.class。

这也揭开了另一个迷:为什么静态内容在一个对象中(不管是emp还是emp2)改变了,在另一个对象中也同时改变,因为这两个对象改变的都是在Employee.class同一个对象里面的内容。

现在,上面说到的第一个论点我们要取消了。因为,静态内容确实被证实属于一个对象。

但是我们还要确认第二个论点:正如早前提到的,原始类型在Java中不是对象,它们无法做类似对象的操作。为了解决这个问题,Java官方为每一个原始类型推出了对应的包装类(比如:Integer对应int,Long对应 long,Character对应char),所以,其实现在我们可以为原始类型创建一个包装对象,同时对它们做对象相关的操作。并且,由于自动拆装箱,我们可以把一个原始类型值赋值给它对应的包装类的引用。但是我们仍然不能对这些原始类型做对象的操作,我们需要创建对应包装类的对象。

例如:

Integer obj = new Integer (5); // here we can do i.toString ();

int i = 5; // but we can't do i.toString () here

到目前为止,从一个最终用户的角度上来看的,我们可以确认 “原始类别不是对象”。(Java 开发人员是 Java的最终用户,因为我们正在使用它,而不是创造它)。

如果站在JVM的视角,会有新的发现:

其实,在JVM看来它把所有的“原始类型”都是当作对象处理,要证明这一点可以通过Class类的源代码或者Javadoc中Class类的说明。

根据 java.lang.Class类的源代码,该类的注释是:

Java 官方描述:

Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

参考译文:

Class 类的实例表示正在运行的Java应用程序的类和接口。像枚举是一种类,注解则是一种接口。每个数组也属于被反射作为由具有相同的元素类型和尺寸的数目的所有阵列共享一类对象的类。原始的Java 类型(boolean, byte, char, short, int, long, float, and double)和关键字void也表示为Class 对象。

同时也根据 Javadoc 中对 Class.isPrimitive ()方法的定义来判断。

Java 官方描述:

public boolean isPrimitive ()

Determines if the specified Class object represents a primitive type.

There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as t he primitive types that they represent, namely boolean,byte, char, short, int, long, float, and double.

These objects may only be accessed via the following public static final variables, and are the only Class objects for which this method returns true.

Returns:

true if and only if this class represents a primitive type

Since:

JDK1.1

参考翻译:

public boolean isPrimitive ()

判断指定的 Class 对象是否代表一个基本类型。

一共有 9 种设定好的 Class 对象来表示对应的基本类型和 void 关键字。这些对象都是由 JVM 创建的。

return

当且仅当该类表示一个真正的基本类型

以上都说明,在 JVM 内部,其实原始类型就是对象。

当你打开 Javadoc对 Class 类的定义中,通过 “CTRL+F ” 查找关键字“primitive”,将会发现证据在表面 “在JVM里,它把基本类型当作对象来处理的”。

我们可以再来看一个例子: Integer.TYPE,在这部分文档清晰记录着:

Java 官方描述:

public static final Class TYPE

The Class instance representing the primitive type int.

以上都说明,在 JVM 内部,其实原始类型就是对象。

那么,既然说 “JVM”会为所有的基本类型创建一个对象,那我们为什么还那么常用 “原始类型”, 而不是直接使用对应的包装类对象呢?

这是因为,为“原始类型”创建的对象,在JVM内部是很轻量级的,相对与我们直接创建的对应包装类对象做了许多优化; 也正因为轻量的缘故,这些原始类的功能就比较少(例如我们不能调用其内部的方法,因为他们内部已经优化成没有方法了)

使用实际的例子来说明,为什么我们更应该使用 “原始类型”:

“原始类型”有更快的速度(例如,下面的代码执行,在我们的机器上需要9秒,但当我把Long改成long 之后,0 秒内就完成了)

public static void main (String[] args) {

long millis = System.currentTimeMillis ();

Long sum = 0L; // uses Long, not long

for (long i = 0; i <= Integer.MAX_VALUE; i++) {

sum += i;

}

System.out.println (sum);

System.out.println ((System.currentTimeMillis () - millis) / 1000);

}

“原始类型”允许我们直接使用 “==”来进行比较。

new Integer (3) == new Integer (3); // false

new Integer (100) == new Integer (100); // false

Integer.valueOf (5) == Integer.valueOf (5); //true

Integer.valueOf (200) == Integer.valueOf (200); //false

我们注意看第四句,输出结果确实为 “false” 。这个是因为在 [-128; 127] 这个区间的265个整数会被JVM 缓存存放, 所以在这个区间, JVM 返回相同的对象;然而,超出这个区间, JVM 就不再有缓存了,将会创建新的对象,所以结果是不等的。

所以总结一下是:

在JVM内部,原始类型就是被当作对象来处理的。但是我们开发者直接把“原始类型”当作对象使用,开发者应该使用对应的包装来。

以上就是为什么我说“Java确实是一个纯粹的面向对象语言”的证实过程。

java面向对象语言_Java到底是不是一种纯面向对象语言?相关推荐

  1. java 纯面向对象_Java到底是不是一种纯面向对象语言?

    原标题:Java到底是不是一种纯面向对象语言? Java--是否确实的 "纯面向对象"?让我们深入到Java的世界,试图来证实它. 在我刚开始学习 Java 的前面几年,我从书本里 ...

  2. long java 比较_Java到底是不是一种纯面向对象语言?

    Java--是否确实的 "纯面向对象"?让我们深入到Java的世界,试图来证实它. 在我刚开始学习 Java 的前面几年,我从书本里知道了 Java 是遵循 "面向对象编 ...

  3. 纯java程序意味着什么_Java到底是不是一种纯面向对象语言?

    在我刚开始学习 Java 的前面几年,我从书本里知道了 Java 是遵循 "面向对象编程范式(Object Oriented Programming paradigm)"的.在Ja ...

  4. java 面向组件_Java 面向对象

    面向对象: 1, 面向过程的思想 准备去一个地方: 先买车, 挂牌, 开导航, 踩油门, 过黄河, 穿越珠穆朗玛峰... 2, 面向对象的思想 我开着车去, 车怎么去随便 所有去这个地方的信息, 全部 ...

  5. java外围设计_Java 编程(23 种设计模式)

    简介 在一般的程序开发过程中,初中级程序员接触的程序设计模式是比较少的.最常见的可能就是单例模式.工厂模式.抽象工厂模式等等,但实际上程序中的设计模式是非常多的,具体可以分为 23 种设计模式.设计模 ...

  6. java object 引用类型_java中的四种引用类型

    java中的四种引用类型 一.强引用 强引用是最常见的,把一个对象赋给一个引用变量,这个引用变量就是一个强引用.当一个对象被强引用变量引用时,他处于可达状态,它是不会被GC回收的,即使该对象以后永远不 ...

  7. java还值_Java到底是引用传递还是值传递

    前言 前段时间在群里看到类似这样一个问题,下面的代码会输出什么呢? public void test(){ String str = "hello"; change(str); S ...

  8. java程序结构_java程序的三种结构

    从结构化程序设计角度出发,程序有三种结构: 顺序结构: JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行顺序结构是最简单的算法结构,语句与语句之间,框与框之间是按从上到下的顺序 ...

  9. java单例模式 参数_java中的几种单例模式

    目前比较常见的有4种(DCL为懒汉模式的线程安全版本). 单例模式的实现一般需要满足以下条件: 1.构造方法私有化,实例属性私有化. 2.必须仅在类的内部完成实例的初始化过程. 3.提供公共静态方法, ...

最新文章

  1. python给用户输出提示_python3.4控制用户输入与输出的方法
  2. Intel或将裁员数千人 谋求业务转型
  3. java 命令直接执行(运行)jar 包的几种方法【笔记自用】
  4. AVS3关键技术、性能和复杂度分析
  5. java双引号的转义字符_JAVA中转义字符
  6. C++ Vecctor容器浅析
  7. android 商品筛选_商品关联分析
  8. 常用正则表达式 潇湘博客
  9. TX2Ubuntu16.04远程登录
  10. 【BZOJ1901】Zju2112 Dynamic Rankings 主席树+树状数组
  11. 用程序关闭、注销、重启计算机
  12. 聪明女婿VS刁蛮丈母娘之三十六计【转载】
  13. ADI 485芯片型号
  14. 驱动程序解析及其对硬件和系统发挥效能的重大作用和注意事宜
  15. sql2000 sp3、sql2000 sp4升级补丁下载和安装须知:
  16. 计算机语言排行榜2015,2015年3月编程语言排行榜:F#排名达到11
  17. MySQL 的主从复制原理详解高级
  18. 超简单 Python 头像戴圣诞帽教程
  19. oracle 虚拟表 多行,Oracle使用虚拟表dual一次插入多条记录【摘录】
  20. [小说]魔王冢(63)正牌蚩尤

热门文章

  1. 《大数据原理:复杂信息的准备、共享和分析》一一2.5 在标识符中嵌入信息:不推荐...
  2. PHP里10个鲜为人知但却非常有用的函数
  3. mysql+phpmyadmin配置流程
  4. Windows 2003性能监视器中的计数器名称变成数字的解决方法
  5. div不能控制tr和td的隐藏
  6. MMDetectionV2 + Colab
  7. C#:WinForm无边框窗体移动方法、模仿鼠标单击标题栏移动窗体位置
  8. 使用iai_kinect2标定kinectV2相机
  9. 嵌入式系统中看门狗概述。。。
  10. CMOS图像传感器——噪声模型