类和类型之间的区别

作为 Java 的新手,我对 同学们类型的概念感到困惑。 例如,对象 "Hello World!"应该属于 类型String还是 同学们String? 或者两者兼而有之?

45804 次浏览

类是一种类型。接口是一种类型。基元是一种类型。数组是一种类型。

因此,每种类型也可以是类(包括枚举常量)、接口、基元或数组。

有两种截然不同的类型: 基本类型和引用类型:

  • 基元类型的变量始终保存同一类型的基元值。这样的值只能通过对该变量的赋值操作来更改。
  • 引用类型的变量始终保存对对象的引用的值。所有对象(包括数组)都支持类 Object的方法。引用类型是类类型(包括枚举类型)、接口类型和数组类型。

每一块数据都有一个定义其结构的类型,即它占用了多少内存,它是如何布局的,更重要的是,您如何与它交互。

基元类型的示例:

  1. int
  2. float
  3. char
  4. boolean

类别的例子:

  1. String
  2. Integer
  3. Boolean
  4. ArrayList
  5. StringBuilder

接口类型的例子:

  1. Collection
  2. List
  3. Map
  4. Serializable

数组类型的示例:

  1. int[]
  2. String[]
  3. Integer[][][]

基本上,任何可以引用为变量的东西都有一个类型,而类就是一种类型。

更多信息请点击: http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html

“类型”是更具包容性的类别。Java 中的变量可以有三种类型: 8种“原始”类型,如 int 和 float、接口和类。值(与变量相反)可以是原语或类实例。

“ Type”定义“它是什么类型的数据”

例如: “ hello world”是一个 String —— > “ hello world”是一个 String 类型(String 与 int 不同,不是一个预设数据。.所以我们可以说“ hello world”是一个字符串类型)

10是一个 int —— > 10是一个整数数据类型。

TLDR -Class 是 Java 中的 Type 之一。

注意-要完全理解答案,你必须对 Java的类型擦除有一点点了解。


为了理解这种差异,让我们首先理解什么是 Java 中的 类型

根据 JLS SE 10,

Java 编程语言中有两种 类别: 基元类型 (4.2)和 引用类型(4.3)。

什么是原始类型?

A)整数类型为 Byte short int 和 long,其值为 8位,16位,32位和64位有符号二进制整数, 以及值为16位无符号整数的 夏尔, 代表 UTF-16编码单位(3.1)。

B)浮点类型为 漂浮,其值包括32位 IEEE 754浮点数和 双倍,它们的值包括 64位 IEEE 754浮点数。

C) 布尔型类型正好有两个值: true 和 false。

现在,让我们来看看什么是引用类型?

有四种参考类型: 班级类型(8.1) ,< strong > interface 类型 (9.1) ,类型变量(4.4)和 数组类型(10.1)

让我们一一讨论。

如果您看到 JLS 中如何定义 同学们,它是这样的:

类声明指定一个新的命名引用类型。

有两种类声明: < strong > 普通类声明 和枚举声明 .

ClassDeclaration:
NormalClassDeclaration
EnumDeclaration
NormalClassDeclaration:
{ClassModifier} class TypeIdentifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody

你可以看到 [TypeParameters],这表明类类型包括 泛型类。

class Example<T>{


}

类类型将被称为 Example

简而言之,类类型涵盖了我们的枚举、常规(非泛型)类(如 String等)和泛型类。

类似地,我希望接口和数组类型也是清楚的。我们所说的数组类型是指像 int[]String[]等等。

让我们来看看最后一个部分类型变量。它们是什么?

类型变量是用作类中类型的非限定标识符, 接口、方法和构造函数体。

让我们通过下面 JLS 中的例子来理解它。

class Test {
<T extends C & I> void test(T t) {
t.mI();           // OK
t.mCPublic();     // OK
t.mCProtected();  // OK
t.mCPackage();    // OK


}
}

可以看到 method 参数中的对象是 T类型的。是的,这个 T是 Type 变量,可以作为参考。是的。(无法理解这个奇怪的例子——学习 Java 中的泛型方法是什么)

这就是答案。

这是一个关于编程术语的问题,正如预期的那样,还有另一个答案可以被认为是有效的。

反射 API 公开的 Java 类型系统有两种类型: Class<T>类和 Type接口,前者实现了这两种类型。在这个系统中,类(由 Class<T>的实例描述的元素)是用关键字 classinterface创建的任何类型、任何基元类型、任何数组和 void。其他的都是 Type

那么其他的事情是什么?虽然在此上下文中的类是运行库在考虑对象的功能时看到和访问的所有内容,但类型通常是编译器看到的所有内容。这可以是 参数化类型参数化类型(类似于 ArrayList<String>——记住类型擦除会导致每个 ArrayList<T>在运行时映射到同一个类)、作为方法或类声明的一部分创建的 泛型类型参数泛型类型参数通配符类型通配符类型和任何 数组。这些类型通过 API 方法在类型擦除不起作用的所有地方公开, 例如,当遍历参数类型或基类型时。

类型与编译时实体(如变量和表达式)关联,而类与运行时实体(如内存中对象)关联。考虑规范 表达式和运行时检查中使用的语言

如果表达式的类型是引用类型,则 被引用的对象... 类型为引用类型的表达式可以使用 instanceof进行测试,以确定该表达式的运行时值所引用的对象的类是否..。

罗伯特哈珀,作者的 编程语言实用基础,使以下 区别

我确实认为仔细区分类别很重要 被附加到对象,从类型,这是静态分类器

Java 泛型就是这种区别相关的一个例子

String greeting = "Hello" + " " + "world!";
  • 变量 greeting的编译时类型是 String
  • 表达式 "Hello" + " " + "world!"的编译时类型是 String
  • 变量 greetings引用的实例化对象 Hello world!的运行时类是 String

在上面的例子中,区别并不重要,但是让我们在下面的代码片段中尝试类似的推理

List<String> greetings = List.of("Hello World!");
  • 变量 greetings的编译时类型是 List<String>
  • 表达式 new ArrayList("Hello World!")的编译时类型是 List<String>
  • 变量 greetings引用的实例化对象的运行时类是 ImmutableCollections$List1

现在我们看到类型 List<String>和类 ImmutableCollections$List1之间确实存在差异。我们看到编译时类型在信息方面“更丰富”,编译器知道元素类型是 String,而在运行时,元素类型信息由于类型擦除而丢失。

下面是关于类型和类之间差异的另一个演示

jshell> /set feedback verbose
|  Feedback mode: verbose


jshell> List.of("Hi", "Hello")
$1 ==> [Hi, Hello]
|  created scratch variable $1 : List<String>


jshell> List.of(42, -11)
$2 ==> [42, -11]
|  created scratch variable $2 : List<Integer>


jshell> $1.getClass() == $2.getClass()
$3 ==> true
|  created scratch variable $3 : boolean

注意表达式 List.of("Hi", "Hello")List.of(42, -11)的类型是如何不同的,但是对应的实例化对象的类是相同的。