班级名称

在Java中,每个类都有一个名称。 类位于软件包中,这使我们程序员可以一起工作,避免名称冲突。 我可以为A类命名,也可以为A类命名,只要它们位于不同的程序包中,它们就可以很好地协同工作。

如果您查看Class的API,您肯定会注意到有三种不同的方法为您提供类的名称:

  • getSimpleName()为您提供不带包的类的名称。
  • getName()为您提供类的名称,其全包名称位于前面。
  • getCanonicalName()为您提供类的规范名称。

简单吗? 好吧,第一个很简单,第二个也很有意义,除非存在令人不安的规范名称。 这还不是很明显。 而且,如果您不知道规范名称是什么,您可能还会在第二时间受到Java技能的干扰。 两者有什么区别?

如果您想要精确的解释,请访问Java语言规范6.7章 。 在这里,我们进行一些更简单,更简单的理解,尽管不够全面。

让我们看一些例子:

package pakage.subpackage.evensubberpackage;
import org.junit.Assert;
import org.junit.Test;public class WhatIsMyName {@Testpublic void classHasName() {final Class<?> klass = WhatIsMyName.class;final String simpleNameExpected = "WhatIsMyName";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName";Assert.assertEquals(nameExpected, klass.getName());Assert.assertEquals(nameExpected, klass.getCanonicalName());		}
...

这种“单元测试”运行得很好。 但是正如您所看到的,在这种情况下,名称和规范名称没有区别。 (请注意,程序包的名称是pakage而不是package 。要测试您的Java词汇技巧,请回答为什么?)

让我们看一下来自同一junit测试文件的下一个示例:

@Testpublic void arrayHasName() {final Class<?> klass = WhatIsMyName[].class;final String simpleNameExpected = "WhatIsMyName[]";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "[Lpakage.subpackage.evensubberpackage.WhatIsMyName;";Assert.assertEquals(nameExpected, klass.getName());final String canonicalNameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName[]";Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());		}

现在有区别。 当我们谈论数组时,简单名称会发出信号,即在其后面加上了括号,就像在Java源代码中所做的那样。 “普通”名称看起来有点怪异。 它以L开头并附加分号。 这反映了JVM中类名的内部表示。 规范名称的更改类似于简单名称:对于以前的类,其类具有所有包名称作为前缀并附加了方括号。 似乎getName()更像是类的JVM名称,而getCanonicalName()更像是Java源代码级别的完全限定名称。

让我们继续其他示例(我们仍在同一文件中):

class NestedClass{}@Testpublic void nestedClassHasName() {final Class<?> klass = NestedClass.class;final String simpleNameExpected = "NestedClass";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$NestedClass";Assert.assertEquals(nameExpected, klass.getName());final String canonicalNameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName.NestedClass";Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());		}

区别在于班级名称中的美元符号。 同样,“名称”更多是JVM使用的名称,而规范名称是Java源代码之类的名称。 如果编译此代码,则Java编译器将生成以下文件:

  • WhatIsMyName.class
  • WhatIsMyName$NestedClass.class

即使该类被命名为嵌套类,它实际上也是一个内部类。 但是在命名上没有什么区别:另一个类中的静态或非静态类仅被命名为相同。 现在,让我们看一些更有趣的东西:

@Testpublic void methodClassHasName() {class MethodClass{};final Class<?> klass = MethodClass.class;final String simpleNameExpected = "MethodClass";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$1MethodClass";Assert.assertEquals(nameExpected, klass.getName());final String canonicalNameExpected = null;Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());}

这次我们在方法内部有一个类。 这不是通常的情况,但是从Java语言的角度来看是有效的。 类的简单名称就是这样:类的简单名称。 没什么奇怪的。

但是,“正常”名称很有趣。 Java编译器为该类生成一个JVM名称,该名称中包含一个数字。 为什么? 因为没有什么可以阻止我在测试类的另一个方法中拥有一个具有相同名称的类,并插入数字是防止JVM名称冲突的方法。 JVM不了解或不关心内部和嵌套类或方法内部定义的类。 一类就是一类。 如果编译代码,则可能会看到javac生成的文件WhatIsMyName$1MethodClass.class 。 我不得不添加“可能”不是因为我认为您可能会盲目,而是因为该名称实际上是Java编译器的内部问题。 它可能会选择其他避免名称冲突的策略,尽管我不知道有什么不同于上面的编译器。

规范名称是最有趣的。 它不存在! 它为空。 为什么? 因为您不能从定义它的方法之外访问此类。 它没有规范名称。 我们继续。

匿名类呢? 他们不应该有名字。 毕竟,这就是为什么它们被称为匿名的原因。

@Testpublic void anonymousClassHasName() {final Class<?> klass = new Object(){}.getClass();final String simpleNameExpected = "";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "pakage.subpackage.evensubberpackage.WhatIsMyName$1";Assert.assertEquals(nameExpected, klass.getName());final String canonicalNameExpected = null;Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());}

实际上,它们没有简单的名称。 简单名称是空字符串。 它们确实具有名称,但由编译器组成。 较差的javac没有其他选择。 它甚至必须为未命名的类组成一些名称。 它必须为JVM生成代码,并且必须将其保存到某个文件中。 规范名称再次为null。

我们已经准备好示例了吗? 否。最后我们有一些简单的东西(又称原始)。 Java基元。

@Testpublic void intClassHasName() {final Class<?> klass = int.class;final String intNameExpected = "int";Assert.assertEquals(intNameExpected, klass.getSimpleName());Assert.assertEquals(intNameExpected, klass.getName());Assert.assertEquals(intNameExpected, klass.getCanonicalName());}

如果该类表示一个原语,例如int (还有什么比int更简单?),则简单名称,“ the”名称和规范名称都全部是该原语的int名称。

就像原始数组一样非常简单吗?

@Testpublic void intArrayClassHasName() {final Class<?> klass = int[].class;final String simpleNameExpected = "int[]";Assert.assertEquals(simpleNameExpected, klass.getSimpleName());final String nameExpected = "[I";Assert.assertEquals(nameExpected, klass.getName());final String canonicalNameExpected = "int[]";Assert.assertEquals(canonicalNameExpected, klass.getCanonicalName());}

好吧,这并不简单。 名称为[I ,这有点神秘,除非您阅读JVM规范的相应章节 。 也许我再说一次。

结论

类的简单名称很简单。 对于JVM级别的事情, getName()返回的“名称”是一个有趣的东西。 getCanonicalName()是最像Java源代码的那个。

  • 您可以从GitHub的g789 e789d700d3c9abc6afa0获得上述示例的完整源代码。

翻译自: https://www.javacodegeeks.com/2014/09/name-of-the-class.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MDK升级后的头文件冲突

////TITLE:// MDK升级后的头文件冲突//AUTHOR:// norains//DATE:// Friday 17-June-2011//Environment:// Keil MDK 4.2// .NET Micro Framework Porting 4.1// 因为在移植的时候&#xff0c;发现了不少MDK编译的一些问题&#xff0c;于是便想升级到最新版本&a…

内置假对象

尽管模拟对象是进行单元测试的理想工具&#xff0c;但通过模拟框架进行模拟可能会将您的单元测试变成难以维护的混乱。 这种复杂性的根本原因是我们的对象太大。 他们有很多方法&#xff0c;这些方法返回其他对象&#xff0c;这些对象也有方法。 当将此类对象的模拟版本作为参…

微信小程序面试题

小程序与原生App哪个好&#xff1f; 答&#xff1a; 小程序除了拥有公众号的低开发成本、低获客成本低以及无需下载等优势&#xff0c;在服务请求延时与用户使用体验是都得到了较大幅度 的提升&#xff0c;使得其能够承载跟复杂的服务功能以及使用户获得更好的用户体验。 简单…

阻止默认事件

在JS中经常需要阻止元素的默认事件。而阻止默认事件的方法都是使用事件对象的preventDefault()方法或者在函数中return false。在最近一次开发中使用preventDefault()方法的时候遇到一个问题&#xff0c;现在才想/猜明白原因&#xff0c;场景是这样的&#xff1a; <a href&…

MySQL之SQL优化详解(三)

目录 MySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化2. 剖析报告:Show ProfileMySQL 之SQL优化详解&#xff08;三&#xff09; 1. 索引优化 一旦建立索引&#xff0c;select 查询语句的where条件要尽量符合最佳左前缀的原则&#xff0c;如若能做到全值匹配最好。…

jUnit:规则

规则在测试&#xff0c;测试用例或测试套件周围增加了特殊处理。 他们可以对类中的所有测试执行通用的其他验证&#xff0c;并发运行多个测试实例&#xff0c;在每个测试或测试用例之前设置资源&#xff0c;然后将其拆除。 该规则可以完全控制将要应用到的测试方法&#xff0c…

常用浏览器内核:

浏览器内核又可以分为两部分&#xff1a;渲染引擎和JS引擎。 PC端&#xff1a;IE&#xff1a;Trident&#xff0c;沿用到IE11,即兼容模式。 IE8 的 JavaScript 引擎是 Jscript&#xff0c;IE9&#xff08;PS: JS内核&#xff09; 开始用 Chakra&#xff0c;这两个版本区别很大…

行内格式化

相对于熟知的块级格式化上下文&#xff0c;行内格式化上下文更加的复杂难明。行内元素不像块级元素那样直来直去&#xff0c;一个块级元素占据一行&#xff0c;其他块级元素在垂直方向依次向下排列即可。行内元素不同&#xff0c;多个行内元素可以在一行显示&#xff0c;那么&a…

[转载]struts+hibernate遇到的错误总结

原文地址&#xff1a;strutshibernate遇到的错误总结作者&#xff1a;畫上句號经过对strutshibernate几天的学习&#xff0c;大体上还算比较的了解机制&#xff0c;以前学习的时候都是 单个框架训练&#xff0c;没有结合2个框架做&#xff0c;所以今天就找了个网上发布租房信息…

JPA休眠替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?

你好&#xff01;你好吗&#xff1f; 今天&#xff0c;我们将讨论不建议使用JPA / Hibernate的情况。 在JPA领域之外&#xff0c;我们还有哪些选择&#xff1f; 我们将谈论的是&#xff1a; JPA /休眠问题 解决一些JPA /休眠问题的方法 选择此处描述的框架的标准 Spring J…

一个Web前端自学者的自述

想来想去还是写下这篇文章&#xff0c;先说明&#xff0c;我精通JAVA编程语言和web前端常见的技术&#xff0c;个人是做JAVA的多&#xff0c;但是更加喜欢前端。因为我从高一开始接触JAVA&#xff0c;家父是黑马的JAVA讲师&#xff0c;自己对编程很热爱&#xff0c;在大学的时候…

mongoose中的populate之多级填充,嵌套字段填充?

在mongoose中存引用的时候如果是多级&#xff0c;查询的时候填充引用字段会使用populate&#xff0c;如下&#xff1a; 定义一个User&#xff0c;有字段friends每一项是自己collection的ObjectId。 // file: user-schema.js let mongoose require(mongoose) let ObjectId m…

深度学习优化基础

1、网络优化参数 sigmoid函数&#xff1a;1/(1e^(-x))&#xff1a;&#xff1a;便于求导的平滑函数&#xff0c;但是容易出现梯度消失问题&#xff1b;函数中值不是0&#xff0c;会导致模型训练的收敛速度变慢。。。 tanh函数&#xff1a;(e^x-e^(-x))/(e^xe^(-x))::解决了zero…

稳定高效大型系统架构---集群中间件开发

那现在来说&#xff0c;稳定的中间件应该是什么样子呢&#xff1f; 对于客户端请求&#xff0c;如果发现服务停止&#xff0c;可以实现服务无缝转移&#xff0d;&#xff0d;&#xff0d;这叫不丢失任何服务. 对于多个客户端请求&#xff0c;可以讲请求轮巡到不同的服务器上&am…

css实现web前端最美的loading加载动画!

这些好看的loading效果&#xff0c;你还只会用第三方库吗&#xff1f;CSS3教你实现 ​前言 loading效果在实际开发中是很常见的&#xff0c;尤其是在Ajax请求的时候&#xff0c;可以给用户一个很好的交互体验。 今天这篇文章我们一起来看看如何通过CSS3实现各种不同的loadin…

如何使用Hibernate从Play生成DDL脚本! 框架项目

好的&#xff0c;因此您一直在使用hibernate属性名称“ hibernate.hbm2ddl.auto ” value “ 更新 ”来不断更新数据库架构&#xff0c; 但是现在您需要一个完整的DDL脚本吗&#xff1f; 从您的Global Class onStart中使用此方法来导出DDL脚本。 只需为其提供实体的包名称&…

C# 设计模式,工厂方法

C#工厂方法 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Threading.Tasks;6 7 namespace 工厂方法 {8 class Program {9 static void Main(string[] args) { 10 IFacotry i new Fact…

javascript中令人迷惑的this

JS中的this很多时候会让人捉摸不透&#xff0c;不知道这个this到底指向的是什么。现在根据自己的理解写下这篇文章做一个总结。 我们知道this指向谁一般情况下是在运行时决定的&#xff0c;并且运行时决定this指向的因素又有很多&#xff0c;例如是不是被bind了&#xff0c;或…

容易忽视但是功能灰常强大的Java API(五. 二分查找)

五. 二分查找 二分查找是一个高效的查找算法&#xff0c;在java的集合对象中也提供了二分查找的算法&#xff0c;如下面的java api接口&#xff1a; java.util.Arrays.binarySearch(java.lang.Object,java.lang.Object,java.util.Comparator) java.util.Arrays.binarySear…

打印 PRINT

打印 PRINT 字符串和数值类型 可以直接输出。 print(1) #out:1 print(a) #out:a 变量 无论什么类型&#xff0c;数值&#xff0c;字符串&#xff0c;列表&#xff0c;字典...都可以直接输出 n 1 s a list_a [1,3,4] dict_c {a:3,b:4} print(n) #out&…