Java--"this "与 "class.name.this "和 "class.name.class "的区别及详解
引言:
对于以上三个语法结构的区分,需要先理解Class类 所有对象的类以及调用了静态方法的类都需要在对象创建之前在JVM虚拟机中加载,加载内容被称为“类对象”,每个类的类对象是唯一且是不可变的。而在对象创建的时候,由于类对象已加载,所以可以添加上类型标签。
1. Class类介绍:
此类的介绍是为了解释 类名.class
的含义。
1.1 Class类简介:
- Class类只有私有的构造方法,所以不能使用new关键词来创建一个Class对象;只有JVM虚拟机可以创建一个类对象,且是在类加载的时候被调用的。
- 运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
- 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象,和其名字相同的类对象名。
- 每个数组属于被映射为 Class 对象的一个类,所有具有相同类型和维数的数组都共享该 Class 对象。只不过数组对象的名字比较奇怪
- 一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
1.2 得到类对象的三个方法:
虽然我们不能使用构造器得到Class对象,但是却可以通过其他方法得到:(注意,class对象可以是接口)
我们先创建一个对象,比如: String
类: String str = new String("Hello World");
方法1:通过 对象.getClass()
得到对象类(非静态方法):
Class classOfString=str.getClass();
注意事项:getClass
方法继承于Object
类,是一个native
方法
方法2:通过Class
类的静态方法forName()
返回类对象:
try {
Class classOfString2=Class.forName("java.lang.String");
System.out.println(classOfString2);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
注意事项:
-
forNanme()
方法会抛出异常ClassNotFoundException
,所以需要使用try-catch
语句捕获。 -
forName
方法输入参数为类名,而不是对象名,并且要完整写出类路径,否则会抛出异常
方法3:通过类名.class
返回此类对象(非静态方法):
Class classOfString3=String.class;
介绍完以上三种方法,不仅知道了得到Clas对象的方法,也知道了类名.class是什么意思了,其就是返回类名所对应的唯一类对象。
1.3 Class类的常用方法:
-
getName()
其原理上调用了一个本地私有方法的非静态方法,返回String类型的实例,代表Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 -
newInstance()
此方法用于返回一个类对象的实例,实例构造只能无参构造器,且为弱类型(即Object类型)。 例子:
try {
String s =(String) classOfString.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
可见由于newInstance返回的是Object类型,所以需要额外向下强制转型。
-
getClassLoader()
返回该类的类加载器。 -
getComponentType()
返回表示数组组件类型的 Class。 -
getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 -
isArray()
判定此 Class 对象是否表示一个数组类。
2. this关键词:
this关键字的三大应用:
- this调用本类中的属性,也就是类中的成员变量,例如:set和构造器中经常使用this关键字(与输入方法的输入参数同名了);
- this调用本类中的其他方法,但通常this可以省略;
- this调用本类中的其他构造方法,调用时要放在构造方法的首行,this()方法可以为有参,也可以为无参(重载)。
总之,关键字this用于指代当前的对象。因此,类内部可以使用this作为前缀引用实例域以及方法(包括构造方法);
3. 类名.this :
类名.this
一般用于内部类调用外部类的对象时使用,因为内部类使用this.
调用的是内部类的域和方法,为了加以区别,所以使用类名.this
来加以区分。例如以下代码:
class OuterClass {
final String str = "OuterClass";
private InnerClass innerClass;
public InnerClass getInner() {
innerClass = new InnerClass();
return innerClass;
}
class InnerClass {
final String str = "InnerClass";
final String str2 = this.str;//指向内部类的域
final String str3 = OuterClass.this.str;//指向外部类的域
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.getInner();
System.out.println(innerClass.str);
System.out.println(innerClass.str2);
System.out.println(innerClass.str3);
}
}
控制台输出:
InnerClass
InnerClass
OuterClass
4.总结
组合 |
用法说明 |
---|---|
this |
指代当前对象的引用 |
类名.class |
指向每个类对应的唯一类对象(类型为Class) |
类名.this |
内部(可以是匿名内部类)类调用外部类的对象时使用,即在内部类中使用时:外部类对象是外部类名.this,内部类对象则是this |
上一篇: 通过源代码分析 Java 中的资源加载
下一篇: jvm 学习 - 类加载器
推荐阅读
-
Java--"this "与 "class.name.this "和 "class.name.class "的区别及详解
-
ARM7、ARM9、ARM11与ARM Cortex系列架构的区别和联系详解
-
基于Node、Vue 3和MySQL的前后端分离开发实践:打造视频上传及显示功能 —— 功能规划与实现详解
-
C++中的单例模式:详解懒汉式与饿汉式的区别(优势与劣势及优化策略)
-
ML里的模型档案详解:深度学习与机器学习中常用的.h5和.keras模型文件介绍、海量下载资源合集及详尽操作指南
-
图的存储与基本操作详解:邻接矩阵和邻接表方法及C/C++代码示例
-
理解域名层次:一级域、二级域与三级域的区别与应用" "*域名、主域名、子域名详解:对SEO的影响及使用决策" "搭建网站时:二级域名与子目录的选择指南" "详解如何在*域下设置Apache的二级域名" "初学者必读:挑选理想域名的五大关键建议" "构建网站时,一级域名与二级域名的实践配置教程
-
玩转Java底层:JMX详解 - jconsole与自定义MBean监控工具的实际应用与区别" 在日常JVM调优中,我们熟知的jconsole工具通过JMX包装的bean以图形化形式展示管理数据,而像jstat和jmap这类内建监控工具则由JVM直接支持。本文将以jconsole为例,深入讲解其实质——基于JMX的MBean功能,包括可视化界面上的bean属性查看和操作调用。 MBeans在jconsole中的体现是那些可观察的组件属性和方法,如上图所示,通过名为"Verbose"的属性能看到其值为false,同时还能直接操作该bean的方法,例如"closeJerryMBean"。 尽管jconsole给我们提供了直观的可视化界面,但请注意,这里的MBean并非固定不变,开发者可根据JMX提供的接口将自己的自定义bean展示到jconsole。以下步骤展示了如何创建并注册一个名为"StudyJavaMBean"的自定义MBean: 1. 首先定义接口`StudyJavaMBean`,接口需遵循MBean规范,即后缀为"MBean"且包含getter方法代表属性,如`getApplicationName`,和无返回值的setter方法代表操作,如`closeJerryMBean`。 ```java public interface StudyJavaMBean { String getApplicationName(); void closeJerryMBean(); } ``` 2. 编写接口的实现类`StudyJavaMBeanImpl`,实现接口中的方法: ```java public class StudyJavaMBeanImpl implements StudyJavaMBean { @Override public String getApplicationName() { return "每天学Java"; } @Override public void closeJerryMBean() { System.out.println("关闭Jerry应用"); } } ``` 3. 在代码中注册自定义MBean,涉及的关键步骤包括: - 获取平台MBeanServer - 定义ObjectName,指定唯一的MBean标识符 - 注册MBean到服务器 - 启动RMI连接器服务,以便jconsole能够访问 ```java public void registerMBean() throws Exception { // ... 具体实现省略 ... } ``` 实际运行注册后的MBean,您将在jconsole中发现并查看自定义bean的属性和调用相关方法。然而,这种方式相较于传统的属性/日志查看和HTTP接口,实用性相对有限,可能存在潜在的安全风险。但不可否认的是,JMX及其MBean机制对于获取操作系统信息、内存状态等关键性能指标仍然具有重要价值。例如: 1. **获取操作系统信息**:通过JMX MBean,可以直接获取到诸如CPU使用率、操作系统版本等系统级信息,这对于资源管理和优化工作具有显著帮助。
-
详解:dBi、dBd、dB、dBm和dBc的区别与含义
-
轻松上手!scss与sass的安装教程及变量和混入功能详解