了解 Java 中的数据类型

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

Java是一个 静态键入编程语言,这意味着当您创建变量时,您还必须指定其 data type,这是它存储的信息类型。

但是,知道数据类型并正确使用它们,可以让开发人员优化他们的代码,因为每个数据类型都有特定的资源要求。此外,如果您指定一个数据类型并尝试存储另一种类型,例如通过错误,您将无法编译代码。

Java有两种数据类型(https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html): primitivereference (也称为 non-primitive)。 在本教程中,您将使用 变量来存储和使用Java程序中的信息,以了解Java中常用的数据类型。

前提条件

要遵循本教程,您将需要:

要在本地计算机上设置,你需要以下内容:

原始类型

Java _primitive types_是Java中最简单和最基本的数据类型,它们代表数字和字符等原始值。 最常用的原始数据类型是int(整数)、boolean(布尔值)和char(字符)。

整合者

[Integers](https://en.wikipedia.org/wiki/Integer_(computer_science)是负数和正整数,在Java中,你会使用int来存储它们,而int可以容纳足够大的数字,用于大多数目的:从2,147,483,6482,147,483,647

让我们看看如何在一个例子中使用int:

1int theAnswer = 42;

原始类型总是以较低的字母(int)开始。Java语法规则要求您先指定数据类型(int),然后指定其名称(theAnswer)。

无论其数据类型如何,您可以直接指定变量名称,而不需要任何特殊字符,因为Java 可以将其识别为变量。

<$>[注] **注:**本教程中的变量名称 theAnswer 和所有其他变量都写在 Camel case中。

一旦你声明了变量,你可以用这样一种方法来引用它:

1int theAnswer = 42;
2System.out.println("The answer to all questions is " + theAnswer);

在第二行中,您将TheAnswer打印到控制台中,使用嵌入式方法printlnSystem.out包中打印,这是测试变量最简单的方式,以确保它按预期声明。

安装 Java 后,在本地计算机上打开终端或命令提示,然后键入jshell:

1jshell

您的输出将看起来如下:

1[secondary_label Output]
2|  Welcome to JShell -- Version 11.0.16
3|  For an introduction type: /help intro
4
5jshell>

您可以将本教程中的代码示例粘贴到控制台中. 一旦完成,您可以通过键入/exit来退出jshell

要声明和使用int,将下列行粘贴到jshell控制台中:

1int theAnswer = 42;
2System.out.println("The answer to all questions is " + theAnswer);

您将看到以下结果:

1[secondary_label Output]
2theAnswer ==> 42
3The answer to all questions is 42

此输出确认您将int变量theAnswer正确设置为 42(theAnswer ==> 42).您还通过将其传递给方法成功使用了theAnswer,该方法产生了预期变量值。

布尔

Boolean值是truefalse。在Java中,你会使用boolean来存储它们。

1boolean isJavaFun = true;

您将变量 isJavaFun 定义为 true. 替代的 boolean 值为 false

使用上述变量,您可以这样打印Java is fun: true的句子:

1boolean isJavaFun = true;
2System.out.println("Java is fun: " + isJavaFun);

jshell中运行这些行将产生以下输出:

1[secondary_label Output]
2isJavaFun ==> true
3Java is fun: true

类似于int示例,方法println会打印插座中提供的参数。加上符号(+)连接或将字符串Java is fun: 与变量isJavaFun合并,所以实际上它只是一个参数 - 字符串Java is fun: true

人物

要存储一个单个字母数字字符,您将使用char

1char firstLetter = 'a';

请注意,字母a被单个引文包围。单个引文只能用于char值。

char 似乎不是一个特别有用的类型,因为您不太可能需要分配给单个字符的变量,但是, char 被用来作为字符串类别的构建块,例如 String,这些字符串基本上是char 值的集合。

正如您在本节中所看到的,原始类型变量的声明和使用是简单的,因为它们代表简单的值,如整数。

参考类型

在本系列的第一个教程中,你了解到Java代码是分类的,并且这些类被用作创建对象的模板。当这些对象被分配给变量时,你指向或指向这些对象。

对象是强大的,因为它们具有先进的属性,并且在触发其方法时可以采取行动,但是,如果没有变量指向它们,这些对象是无法访问的,而且几乎无法使用的,这就是为什么参考类型变量对Java和整体对象导向编程至关重要。

<$>[注] 注: 参考类型指向由类创建的对象. 为了避免混淆,下面的示例中,参考类型和创建的对象将属于相同的类别。

然而,在复杂的程序中,这种情况很少发生。在Java中,一个 interface是特定行为的要求组,并且这些要求可以由一个或多个类满足。符合接口的要求的类被称为实现这个接口。因此,在复杂的程序中,它是常见的,以接口的参考类型声明变量。这样,你可以指定你的变量应该显示的行为,而不会将其绑定到这种行为的具体实施。这使你能够轻松地改变你的变量点的实施,而无需改变变量使用的方式。这个复杂的概念是关于 inheritancepolymorphism 的更高级主题的一部分,这将是我们Java系列中的一个单独的教程。

虽然只有少数原始类型,但参考类型实际上是无限的,因为类(和界面)的数量没有限制,每个类代表一个参考类型。在Java中有许多内置类型提供基本的功能。

《String》班级

字符串类代表构成字符串的字符组合。 要声明一个字符串或任何其他参考类型变量,您首先要指定其类型,然后是其名称。 然后,您将以等价符号分配一个值。 到目前为止,它与原始类型相似。

1String hello = new String("Hello");

「Hello」是引用类型为「String」的变量名称,您将其分配给一个新的「String」对象,新的「String」对象由「新」关键字和类的名称一起创建,在这种情况下,类的名称是「String」。

每个类都有一个称为 constructor 的特殊方法,用于创建新对象. 您可以通过在类名称的末尾添加(())来召唤这个构造者。

要确认Hello变量按预期行为,请将其再次传送到println方法,如下:

1String hello = new String("Hello");
2System.out.println(hello);

jshell中运行这些行将产生以下输出:

1[secondary_label Output]
2hello ==> "Hello"
3Hello

这次,输出确认变量hello设置为Hello,然后在新行上打印相同的Hello,确认方法println()已经处理了它。

包装班级

在上一节中,您使用了常用的字符串参照类型。 其他流行的参照类型是原始类型的所谓的包装。 A wrapper class 包装或包含原始数据,因此其名称。

  • Integer: 要包装 int
  • 字符: 要包装 char
  • Boolean: 要包装 boolean

这些包装器存在,以便您可以将一个简单的原始值升级为一个强大的对象. 每个包装器都有与其设计存储的值相关的可用方法。

作为一个例子,你将探索Integer。在上一节中,你创建了一个String对象,用的关键字。然而,一些类提供,甚至鼓励,使用特殊的方法来从中获取对象,而Integer是其中之一。

在下面的示例中,您将创建一个名为TheAnswerInteger变量,其值为42,使用valueOf方法(https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html#valueOf(int):

1Integer theAnswer = Integer.valueOf(42);
2System.out.println(theAnswer);

jshell中,您将获得以下输出:

1[secondary_label Output]
2theAnswer ==> 42
342

通过调用Integer方法valueOf(42),你指示Java给你一个具有这个值的对象。 幕后,Java 会检查其缓存中是否已经有具有这种值的对象。

许多内置类为性能原因提供此类方法,建议使用它们,如果不是强制性的,那么在Integer的情况下,您仍然可以创建一个具有关键字的对象,但您将收到减值警告。

除了「String」和包装外,还有其他有用的内置参考类型,您可以在 java.lang 套件摘要找到。 为了充分理解一些这些更先进的参考类型,需要额外的解释或先前的知识。

文学

字母表示可以直接在代码中使用的固定值,因此可以分配给原始和参考类型。

原始类型的文学

你已经在原始类型部分中使用了一些字母字母,每个原始类型都有一个字母字母,例如我们示例中的字母字母:‘42’,‘a’和‘true’。

原始类型的字母也可以用来创建参考类型的值. 在创建一个Integer对象时使用了Integer.valueOf(42)代码的int字母。

1Integer theAnswer = 42;

「42」是一個整數字母,就像任何整數一樣,你可以直接將它分配給「答案」變量,而沒有任何額外的陳述。

这种短语方法也适用于其他原始类型的字母和其对应的参考类型,如Boolean,例如:

1Boolean isFun = true;

'true' 是字面值,直接分配给类型的 'isFun' 变量. 还有一个 'false' 字面值,您可以以相同的方式分配。

字面上的 String

还有一个特殊的字母为字符串的参考类型,它是通过围绕它的值的双重引用来识别的。

1String helloWorld = "Hello, World!";

使用字母字符更简单,更短,许多程序员更喜欢使用它,然而,您仍然可以通过一个新的字符串对象来声明一个字符串变量,正如您在参考类型部分中所做的那样。

字面上的零

还有一个重要的字母:‘null’,代表一个值的缺失或对象的不存在。‘Null’允许你创建一个参考类型,并将其指向‘null’,而不是指向一个对象。

有一个警告与null字母:你可以声明变量,但你不能使用这些变量,直到你重新分配一个合适的,非null值. 如果你尝试使用一个参考类型的变量与null值,你会得到一个错误。

1String initiallyNullString = null;
2System.out.println("The class name is: " + initiallyNullString.getClass());

当您尝试在jshell中运行此代码时,您将看到类似于以下的错误:

1[secondary_label Output]
2initiallyNullString ==> null
3|  Exception java.lang.NullPointerException
4|        at (#4:1)

根据您的操作系统和Java版本,您的输出可能会有所不同。

java.lang.NullPointerException 错误是因为您试图在变量initiallyNullString (指向 null 对象) 上调用 String 方法getClass() (返回类的名称)。

<$>[注] **注:**为了简单,我们正在称java.lang.NullPointerException为错误,尽管它在技术上是一个例外。

要解决此错误,您必须重定义 initiallyNullString 值如下:

1String initiallyNullString = null;
2initiallyNullString = "not null any longer";
3System.out.println("The class name is: " + initiallyNullString.getClass());

新的固态代码将打印以下输出:

1[secondary_label Output]
2initiallyNullString ==> null
3initiallyNullString ==> "not null any longer"
4The class name is: class java.lang.String

上面的输出显示最初NullStringnull,然后它变成一个新的字符串对象,其中包含不再 null。接下来,当getClass()方法在实例化对象上被召唤时,你会得到java.lang.String,其中String是类名称和java.lang是其包装。

这种null值声明更为常见于遗传代码,它们被用来创建一个变量,然后再分配它的实际值,通常通过某种逻辑来确定后者,然而,自从Java版本8以来,有一个名为可选(https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)的新参考类型,这更适合以前使用null的情况。

局部变量类型 inference

到目前为止,你一直在使用Java中的一些常见数据类型来定义变量。然而,Java 10引入了一种名为local variable type inference的新功能,它允许你在新变量面前使用关键字var。有了这个功能,Java会从本地背景中推断(即自动猜测)数据类型。类型推断是有争议的,因为它与以前解释过的定义变量口语相矛盾。

在任何情况下,类型推断不能完全取代数据类型的使用,因为它只适用于本地变量,这些变量是方法内部的变量。

1var hello = "Hello";
2System.out.println(hello);

您声明变量你好var关键字,以指示Java检测其数据类型. 然后,您以通常的方式打印到控制台,以确认它按预期工作:

1[secondary_label Ouput]
2hello ==> "Hello"
3Hello

此示例将工作,只要您的Java安装(更具体地说,JDK)在版本10以上。

类型推断发生在编译过程中,也就是说,当您编译代码时。编译过程将简单的文本源代码转换为机器代码,并应用各种优化,包括类型推断。

在本示例中,var关键字是有效的,因为变量是本地的,而var数据类型仅适用于本地变量。

要显示var只能用于本地变量,请尝试将其放置在主方法之外,如下:

1public class Hello {
2    var hello = "Hello";
3    public static void main(String[] args) {
4    	// example code
5    }
6}

当你在jshell中插入上述代码时,你会收到以下错误:

1[secondary_label Output]
2|  Error:
3|  'var' is not allowed here
4|  	var hello = "Hello";
5|   ^-^

因此,类型推断不适用于非本地变量,因为背景无法可靠地使用来检测数据类型。

虽然使用var可能具有挑战性,并且不需要使用,但你可能会遇到它,因此了解它是有用的。

保留关键词

在Java中声明变量时,还有一条重要的规则要知道:有保留的关键字,你不能用到变量名称中,例如,你不能声明一个类型的原始词int,并这样命名它:

1int new = 1;

如果你尝试这个示例,你会收到编译错误,因为是一个保留的关键字。

 1[secondary_label Output]
 2|  Error:
 3|  '.class' expected
 4|  int new = 1;
 5|      ^
 6|  Error:
 7|  <identifier> expected
 8|  int new = 1;
 9|         ^
10|  Error:
11|  '(' or '[' expected
12|  int new = 1;
13|          ^
14|  Error:
15|  unexpected type
16|    required: value
17|    found:    class
18|  int new = 1;
19|  ^--^
20|  Error:
21|  missing return statement
22|  int new = 1;
23|  ^----------^

关键字用于创建新对象,Java在这个位置没有预料到它。

1[secondary_label Output]
2|  Error:
3|  '.class' expected
4|  int new = 1;
5|      ^

等待类错误意味着,当你使用关键字时,Java 会期望一个类会随之而来. 在此时,Java 无法解释这个陈述,其余的错误会随之而来。

其他保留的关键字,如抽象,继续,默认,,在Java中也具有特定含义,不能用于变量名称。

结论

在本教程中,您了解了Java中的原始和参考数据类型,这是一个复杂但至关重要的话题。花时间练习它,并通过示例多次尝试改变一些数据类型和值。

關於Java的更多信息,請參閱我們的 如何在Java中編碼系列。

Published At
Categories with 技术
Tagged with
comments powered by Disqus