作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
Java是一个 静态键入编程语言,这意味着当您创建变量时,您还必须指定其 data type,这是它存储的信息类型。
但是,知道数据类型并正确使用它们,可以让开发人员优化他们的代码,因为每个数据类型都有特定的资源要求。此外,如果您指定一个数据类型并尝试存储另一种类型,例如通过错误,您将无法编译代码。
Java有两种数据类型(https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html): primitive 和 reference (也称为 non-primitive)。 在本教程中,您将使用 变量来存储和使用Java程序中的信息,以了解Java中常用的数据类型。
前提条件
要遵循本教程,您将需要:
要在本地计算机上设置,你需要以下内容:
- Java(版本 11 或更高)安装在你的计算机上,使用由 Java 开发工具包 (JDK)提供的编译器。对于 Ubuntu 和 Debian,按照我们教程中的 选项 1的步骤来编译和运行代码,本教程使用了 Java Shell,其他操作系统,包括 Mac 和 Windows,请参阅 下载选项用于 Java 安装。
- 要编译和运行代码示例,本教程使用了 Java Shell,一个 Read-Evaluate-Print Loop_RE从命令行
原始类型
Java _primitive types_是Java中最简单和最基本的数据类型,它们代表数字和字符等原始值。 最常用的原始数据类型是int(整数)、boolean(布尔值)和char(字符)。
整合者
[Integers](https://en.wikipedia.org/wiki/Integer_(computer_science)是负数和正整数,在Java中,你会使用int
来存储它们,而int
可以容纳足够大的数字,用于大多数目的:从2,147,483,648
到2,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
打印到控制台中,使用嵌入式方法println
从System.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值是true
或false
。在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是特定行为的要求组,并且这些要求可以由一个或多个类满足。符合接口的要求的类被称为实现这个接口。因此,在复杂的程序中,它是常见的,以接口的参考类型声明变量。这样,你可以指定你的变量应该显示的行为,而不会将其绑定到这种行为的具体实施。这使你能够轻松地改变你的变量点的实施,而无需改变变量使用的方式。这个复杂的概念是关于 inheritance 和 polymorphism 的更高级主题的一部分,这将是我们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
是其中之一。
在下面的示例中,您将创建一个名为TheAnswer
的Integer
变量,其值为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
上面的输出显示最初NullString
是null
,然后它变成一个新的字符串
对象,其中包含不再 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中編碼系列。