由"反射的三种方式的区别"引发的知识泥石流

告别Qt Creator!VSCode + QMake + MinGW:从零搭建高效Qt开发环境 本文详细介绍了如何使用VSCode替代Qt Creator搭建高效的Qt开发环境,涵盖VSCode配置、QMake与MinGW集成、智能提示优化及构建调试技巧。通过实战案例展示如何提升开发效率30%以上,特别适合中大型Qt项目开发。 阅读详情

问题来自于反射的三种方式的区别在哪里,由此牵出“构造代码块”这样一个概念,再深究下去就来到了类的加载过程,所以最终还是java虚拟机。
首先是反射的三种方式的区别:

1.类名.class
不做类的初始化工作,返回类的Class对象。
2.Class.forName(String className)
做类的静态初始化,返回类的Class对象。( 如果使用Class.forName(String name, boolean initialize,ClassLoader loader) ,并将initialize的值设为false,则不会进行类的静态初始化)
3.实例对象的getClass()
对类进行静态初始化、非静态初始化(由于首先使用new得到类的实例对象,实际上是这一步对类进行了初始化)。

(以下大部分内容来自于文章:https://cloud.tencent.com/developer/article/1350200,很感谢这位大牛的总结,但是结尾部分,他写错了。。。)

public class Test {
    {
        ////
    }
}

这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起,形成一个独立的数据体,用于实现特定的算法。一般来说代码块是不能单独运行的,它必须要有运行主体。在Java中代码块主要分为四种:

一、普通代码块

普通代码块是我们用得最多的也是最普遍的,它就是在方法名后面用{}括起来的代码段。普通代码块是不能够单独存在的,它必须要紧跟在方法名后面。同时也必须要使用方法名调用它。

public class Test {
    public void test(){
        System.out.println("普通代码块");
    }
}

二、静态代码块

想到静态我们就会想到static,静态代码块就是用static修饰的用{}括起来的代码段,它的主要目的就是对静态属性进行初始化

public class Test {
    static{
        System.out.println("静态代码块");
    }
}

三、同步代码块

使用 synchronized 关键字修饰,并使用“{}”括起来的代码片段,它表示同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制。

四、构造代码块

在类中直接定义没有任何修饰符、前缀、后缀的代码块即为构造代码块。

public class Test {
    {
        System.out.println("构造代码块");
    }
}

它的主要作用有两个:

  1. 初始化实例变量
    如果一个类中存在若干个构造函数,这些构造函数都需要对实例变量进行初始化,如果我们直接在构造函数中实例化,必定会产生很多重复代码,繁琐和可读性差。这里我们可以充分利用构造代码块来实现。这是利用编译器会将构造代码块添加到每个构造函数中的特性。
  2. 初始化实例环境
    一个对象必须在适当的场景下才能存在,如果没有适当的场景,则就需要在创建对象时创建此场景。我们可以利用构造代码块来创建此场景,尤其是该场景的创建过程较为复杂。构造代码会在构造函数之前执行。

上面两个常用场景都充分利用构造代码块的特性,能够很好的解决在实例化对象时构造函数比较难解决的问题,利用构造代码不仅可以减少代码量,同时也是程序的 可读性增强了。特别是当一个对象的创建过程比较复杂,需要实现一些复杂逻辑,这个时候如果在构造函数中实现逻辑,这是不推荐的,因为我们提倡构造函数要尽 可能的简单易懂,所以我们可以使用构造代码封装这些逻辑实现部分。

五、静态代码块、构造代码块、构造函数执行顺序

从词面上我们就可以看出他们的区别。静态代码块,静态,其作用级别为类,构造代码块、构造函数,构造,其作用级别为对象。

  1. 静态代码块,它是随着类的加载而被执行,只要类被加载了就会执行,而且只会加载一次,主要用于给类进行初始化。
  2. 构造代码块,每创建一个对象时就会执行一次,且优先于构造函数,主要用于初始化不同对象共性的初始化内容和初始化实例环境。
  3. 构造函数,每创建一个对象时就会执行一次。同时构造函数是给特定对象进行初始化,而构造代码是给所有对象进行初始化,作用区域不同。

通过上面的分析,他们三者的执行顺序应该为:静态代码块 > 构造代码块 > 构造函数。

public class Test {
    /**
     * 静态代码块
     */
    static{
        System.out.println("执行静态代码块...");
    }

    /**
     * 构造代码块
     */
    {
        System.out.println("执行构造代码块...");
    }

    /**
     * 无参构造函数
     */
    public Test(){
        System.out.println("执行无参构造函数...");
    }

    /**
     * 有参构造函数
     * @param id
     */
    public Test(String id){
        System.out.println("执行有参构造函数...");
    }

    public static void main(String[] args) {
        System.out.println("----------------------");
        new Test();
        System.out.println("----------------------");
        new Test("1");
    }
}

Output:
执行静态代码块…
———————-
执行构造代码块…
执行无参构造函数…
———————-
执行构造代码块…
执行有参构造函数…

六、复杂环境下的执行顺序

一道亚信面试题(经过原作者的修改):

class Print{
 public Print(String message) {
     System.out.println(message);
 }
}
class Parent{
 //静态属性
 private static Print name1 = new Print("Parent static field");
 //属性(成员变量)
 private Print name2 = new Print("Parent field");
 //构造器
 public Parent(){
     System.out.println("Parent constructor");
 }
 //静态代码块
 static{
     new Print("Parent static code block");
 }
 //构造代码块
 {
     new Print("Parent constructor code block");
 }
}
public class Child extends Parent{
 //静态属性
 private static Print name1 = new Print("Child static field");
 //属性(成员变量)
 private Print name2 = new Print("Child field");
 //构造器
 public Child(){
     System.out.println("Child constructor");
 }
 //静态代码块
 static{
     new Print("Child static code block");
 }
 //构造代码块
 {
     new Print("Child constructor code block");
 }
 public static void main(String[] args) {
     new Child();
     System.out.println("---我是分割线---");
     new Child();
 }
}

原文的结果我就不展示了,直接贴正确结果:

Parent static field
Parent static code block
Child static field
Child static code block
Parent field
Parent constructor code block
Parent constructor
Child field
Child constructor code block
Child constructor
—我是分割线—
Parent field
Parent constructor code block
Parent constructor
Child field
Child constructor code block
Child constructor

PL/SQL 中的数据导入和导出:CSV 文件格式详解 在 PL/SQL 开发中,数据的导入和导出是常见的操作。本文将深入探讨如何使用 PL/SQL 导入和导出 CSV 文件格式的数据,帮助你轻松地实现数据迁移、备份和数据交换等需求。CSV(Comma-Separated Values)是一种常见的文本文件格式,它以逗号作为字段的分隔符,每行表示一个记录。使用 CSV 格式可以方便地在不同的系统之间共享和传输数据。下面我们将分步介绍如何在 PL/SQL 中导入和导出 CSV 文件格式的数据。 阅读详情

相关推荐

ElaticSearchUtil工具类封装

package com.xxx.util; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction; import org.elasticsearch.action.ad

会飞的狼 6295

概述java反射_Java反射详细介绍

反射目录介绍1.反射概述1.1 反射概述1.2 获取class文件对象的三种方式1.3 反射常用的方法介绍1.4 反射的定义1.5 反射的组成1.6 反射的作用有哪些2.反射的相关使用2.1.1 通过反射获取无参构造方法并使用2.1.2 通过反射获取带参构造方法并使用2.1.3 通过反射获取私有构造方法并使用2.1.4 通过反射获取成员变量并使用2.1.5 通过反射获取无参无返回值成员方法并使用2...

weixin_32620265的博客 368

分布式 Agent 系统设计:高并发场景下的挑战与解决方案

分布式 Agent 系统由多个分布在不同节点上的智能 Agent 组成,这些 Agent 具有自主决策能力,能够通过通信协作完成复杂任务。每个 Agent 可以看作是一个独立的实体,具备感知环境、处理信息、执行动作的功能,它们相互协作,共同实现系统的整体目标。分布式 Agent 系统在高并发场景下面临着资源调度、通信延迟、状态一致性、容错处理和性能瓶颈等诸多挑战。通过采用动态资源分配、高效通信协议、分布式共识算法、冗余备份等解决方案,可以有效应对这些挑战,提高系统的性能、可靠性和可用性。

shuizhudan223的博客 1292

反射的原理是什么?反射创建类实例有几种方式?

它允许程序在运行时通过名称来获取类的字段、方法和构造函数等信息,并且可以使用这些信息来创建对象、调用方法和访问字段,即使在编译时并未提前知道这些类的存在。这些方式都使用了反射机制来在运行时动态地创建类的实例。反射的原理是通过java.lang.reflect包中的类和接口提供的方法来实现的。与前一种方式不同的是,这种方式可以选择调用类的指定构造函数来创建对象。从Java 9开始,Constructor类提供了一个newInstance()方法的简化写法,可以通过类型推断来省略构造函数的参数类型。

Blue92120的博客 964

基于Matlab与Bladed联合仿真的交互软件设计

基于Matlab与Bladed的交互软件设计

weixin_45014222的博客 815

链接文件及功能安全:英飞凌官方文档摘录 - 基于Tasking与AURIX TC3xx MCAL中Link文件解析以及代码变量定位方法详解

Data区域是用来存放带初始化值的全局变量,在link文件中,这个区域有两种类型,预先定义的区域和默认区域。预先定义的Data区域,例如.data.Ifx_Ssw_Tc1和.data.Cpu1_Main.*,在cpu1_main.c中如果定义了一个带初始化值的变量,则它会放在DSRAM1中的.data.Cpu1_Main.*段中。

梦想技术家 538

java反射三种的区别_面试:说说Java反射中获取Class对象三种方式的区别?

在上篇文章《一篇文章全面了解Java反射机制》中我们学习了Java反射机制的基本使用,留心的朋友可能已经注意到了,在文中提到了三种获取Class对象的方法。如果面试中涉及到Java反射,那么遇到该面试题的概率将大大增加。以下三种获取Class对象的方式有什么不同?1、new Object().getClass 2、Object.class 3、 Class.forName("java.util.S...

weixin_36458030的博客 346

Python控制程控电源(USB)

随着智能电动汽车行业的持续发展,汽车电子或嵌入式设备在软硬件的测试中,都会使用程控电源供电,特别是自动化测试、压力测试场景必定使用到程控电源控制,控制电源上下电,监听电源电流、电压等,以下就以常见的艾德克斯程控电源为例,分享如何通过USB连接方式Python语言来控制程控电源。

测试领域技术分享 2865

java反射三种的区别_JAVA反射与C#反射之比较 | 学步园

一.什么是反射在运行时环境,能否根据一个类的名字,来得到这个类的属性和方法?对于任何一个运行时的对象能否动态调用这个对象的方法?答案是可以的。这种动态的获取类的信息以及动态调用一个对象的方法的机制叫做反射。反射提供的主要功能:1.在运行时判断任意一个对象所属的类2.在运行时构造一个类的对象3.在运行时判断一个类所具有的属性和方法4.在运行时调用一个对象的方法实现反射的过程:1.加载一个类2.根据这...

weixin_39769767的博客 514

从零开始:C#上位机集成YOLO完成摄像头目标追踪(保姆级教程)

新手入门C#上位机+YOLO做摄像头目标追踪,最忌讳的是“只抄代码,不懂逻辑”。这个教程不仅给了完整代码,还把核心原理和踩坑点都讲清楚了,新手跟着走,不仅能跑通demo,还能理解为什么这么写。如果你们在运行时遇到具体问题,比如模型导出失败、代码报错,都可以在评论区留言,我会一一解答。后续也可以出一期工业相机+YOLO目标追踪的教程,帮助大家把demo落地到实际生产中。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1028

ModuleNotFoundError: No module named‘langchain.schema.output parserlangchain.schema is not a package

电脑里现有的langchain库版本与import所需的不同,卸载原有langchain,重新下载最新的langchain。在步骤1后,若仍不可运行。在确保已重新下载新langchain后,重启python后,可正常运行。在版本号中填入所需的langchain版本号,可在requirements.txt查看。运行如下代码时,出现error。

weixin_45751925的博客 1713

有关java反射的几个小方法的作用和区别

1.Class类中 getXXX()和getDeclaredXXX()的作用和区别: 前者获取某个类的所有公共(public)的字段(or方法or构造函数),包括父类。后者获取所有的字段(or方法or构造函数),即所有修饰符修饰的(public,private,protectd),但是并不包括父类的申明字段。 例:getFields()获得某个类的所有的公共(public...

AlexZhang7799的专栏 189

YOLOv11 损失函数解析

YOLOv11 在 YOLO 系列的持续演进中,通过 ​多模态损失协同优化、动态任务感知机制 和 ​超轻量化设计,实现了检测精度与推理效率的再突破。其损失函数设计融合了前沿的几何建模、分布学习与自监督技术,显著提升了复杂场景下的鲁棒性。

浩瀚之水的专栏 6702

Java程序员面试题

java面试题

fang.lovest.yang的博客 313

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

面试:说说Java反射中获取Class对象三种方式的区别?

在上篇文章《一篇文章全面了解Java反射机制》中我们学习了Java反射机制的基本使用,留心的朋友可能已经注意到了,在文中提到了三种获取Class对象的方法。 如果面试中涉及到Java反射,那么遇到该面试题的概率将大大增加。 以下三种获取Class对象的方式有什么不同? 1、new Object().getClass 2、Object.class 3、 Class.forName(“java.ut...

程序新视界 2243

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

JAVA反射(一)获取Class对象的三种方式及其区别

JAVA有三种方式可以获得Class对象 1、通过类名.class方式获得,Class  cType = ClassName.class; public class Client { public static void main(String[] args) { Class cType1 = Test.class; } } class Test{ static {

lynfoolbird的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java反射三种方式的效率对比

Java反射三种方式的效率对比 field, method, BeanUtils

aitcax的专栏 1万+

Java反射的几个方法区别

getFields()与getDeclaredFields()区别:getFields()只能访问类中声明为公有的字段,私有的字段它无法访问,能访问从其它类继承来的公有方法.getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法 getMethods()与getDeclaredMethods()区别:getMet

C_Life 1291

JAVA反射(一):获取Class对象的三种方式及其区别

CLASS 在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息 在运行期间,如果我们要产生某个类的对象,Java虚拟机(JVM)会检查该类型的Class对象是否已被加载。如果没有被加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象

lq851643368的专栏 1538

java 反射 getclass_Java反射中获取Class对象三种方式的区别

Java反射中获取Class有三种方式:new Object().getClassObject.classClass.forName("com.sherlock.demo")以下就详细的讲讲这三种方式的区别首先我们先定义一个Demo类,其中定义了静态代码块、动态代码块和构造函数public class Demo {static {System.out.println("Demo:静态代码块");}...

weixin_39879881的博客 450

java反射三种_java反射

反射概述反射库(reflection library) 提供了一个非常丰富且精心设计的工具集, 以便编写能够动 态操纵 Java 代码的程序。这项功能被大量地应用于 JavaBeans 中, 它是 Java组件的体系结构 (有关 JavaBeans 的详细内容在卷 II中阐述)。使用反射, Java 可以支持 Visual Basic 用户习惯 使用的工具。特别是在设计或运行中添加新类时, 能够快...

weixin_30800961的博客 275

java获取反射机制的三种方式

java 获取反射常使用的三种方式:1.通过new对象实现反射机制2.通过路径实现反射机制3.通过类名实现反射机制例子:建立一个学生类:public class Student { private int id; String name; protected boolean sex; public float score; } 获取反射机制public class Get { //获取...

m_target的博客 1万+

Java反射的三种实现方式

1 Foo foo = new Foo(); 第一种:通过Object类的getClass方法 1 Class cla = foo.getClass(); 第二种:通过对象实例方法获取对象 1 Class cla = foo.class;

刘超军的博客 6539

Java三种反射

1、基本用法 1.通过 .class 获取对象。 2.通过 getClass() 获取对象。 3.通过 Class.forName("") 获取对象。 2、示例代码 public class Reflex { public static void main(String[] args) throws Exception { Class class_1 = ReflexObjec...

qq_27243963的博客 342

java中对反射获取Class类型对象的三种方式的理解

一、反射的作用 1、反编译:从.class文件到.java文件。 2、通过反射机制访问java类的属性,方法,构造方法等。 创建一个普通类: class User{ String name; User(){} public void m1(){} } 以前我们访问属性name,会这样做: User u = new User(); u.name 二、获取Class类...

十豆三展的博客 6870

Java|反射的三种实现方式

第一种 Student stu = new Student(); Class clazz = stu.getClass(); 第二种 Class clazz = Student.class; 第三种 Class clazz = Class.forName("com.jdbc.mysql.Driver");

白衬衫猿 1524
上一篇: 计算机网络中的网络协议
下一篇: 多线程模拟银行家死锁问题
冰箱太凉
博客等级 码龄9年 23粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值