在static块和static方法中如何获取当前类及如何获取当前正在执行的方法

Java面试知识点(四)初始化执行代码顺序(包含static块和构造块)以及类方法和实例方法 (1)在初次 new 一个 Child 类对象时,发现其有父类,则先加载 Parent 类,再加载 Child 类。 (2)加载 Parent 类: 初始化 Parent 类的 static 属性,赋默认值; 执行 Parent 类的 static 初始化块; (3)加载 Child 类: 初始化 Child 类的 static 属性,赋默认值; 执行 Child 类的 static 初始化块; ... 阅读详情

这是我自己在实际中遇到的一个问题,原问题是这样的,就是我有一个工具类 DbUtil,一看名称就知道是和数据库相关的,由于是工具类,所以里面的方法都是static的 ,但是又需要有关 jdbc 的 配置,总部至于硬编码吧,所以就想到了放在和当前类一个目录里,然后用getClass.getResourceAsStream 得到一个InputStream  再来初始化一个 Properties,用其load(InputStream) 来获得属性文件里有关jdbc的配置 ,这个时候才发现了问题,在 static中this不能用,那如何获得当前类的Class呢,在网上搜罗了一番, 没发现这个问题好的解决方案,但是却发现了另一个问题,就是如何在当前方法中获取当前方法名,这个,一听,似乎很不错哦,用过Log4j的朋友,应该知道Log4J是可以打印出来自己在哪个方法里的那行的,而且还可以知道当前类。停,到这应该是该停一下了,思考下,当前类名获取了,那么 Class.forName是做什么的,大脑里有点想法了吧,看网上介绍Log4J关于动态获取当前文件,类,方法,行号的原理,对JDK不同版本也不同了,下面就是Copy 的

一、问题的引入
我们在Java程序中使用日志功能(JDK Log或者Log4J)的时候,会发现Log系统会自动帮我们打印出丰富的信息,格式一般如下:

[运行时间] [当前类名] [方法名] 

INFO: [用户信息]

具体例子如Tomcat启动信息:

Jul 
9, 2004 11:22:41 AM org.apache.coyote.http11.Http11Protocol start 
INFO: Starting Coyote HTTP
/1.1 on port 8080

 

看起来这毫无神奇之处,不就是打印了一条信息吗?但如果好奇心重一点,追寻后面的实现原理,会发现这确实很神奇。

上面的Log信息的[当前类名] [方法名]部分 不是用户自己添加的,而是Log系统自动添加的。这意味着Log系统能够自动判断当前执行语句是哪个类的哪个方法。这是如何做到的?

我们翻遍java.lang.reflection 
package,幻想着找到一个Statement语句级别的Reflection类,通过这个Statement对象获得Method,然后通过这个Method获得declared Class。这不就获得对应的Class和Method信息了吗?这是一个不错的构想,但也只能是一个构想;因为没有这个Statement对象。

再想一下。对了,Java不是有一个Thread类吗?Thread.currentThread()方法获取当前线程,我们能不能通过这个当前线程获取当前运行的Method和Class呢?很遗憾,如果你还在用JDK1.4或以下版本,那么找不到这样的方法。(JDK1.5的情况后面会讲)

再想一下。对了,我们都有很深刻的印象,当系统抛出Exception的时候,总是打印出一串的信息,告诉我们Exception发生的位置,和一层一层的调用关系。我们也可以自己调用Exception的printStackTrace()方法来打印这些信息。这不就是当前线程运行栈的信息吗?找到了,就是它。

Exception的printStackTrace()方法继承自Throwable,那么我们来看一下,JDK的Throwable的printStackTrace()方法是如何实现的。

我们先来看JDK1.3的源代码,会发现Throwable.printStackTrace()方法调用了一个native printStackTrace0()方法。我们找不到任何线索,可以用在我们自己的Java代码中。

那怎么办?Throwable.printStackTrace()的输出结果字符串里面不是包含了当前线程运行栈的所有信息吗?我们可以从这个字符串中抽取自己需要的信息。JDK1.3的时代,也只能这么做了。

二、Log4J 
1.2的相关实现
Log4J 
1.2是JDK1.3时代的作品。我们来看相关源代码。

[code]

  
/**

     Instantiate location information based on a Throwable. We

     expect the Throwable t, to be in the format

       
        java.lang.Throwable

        ...

          at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)

          at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)

        at org.apache.log4j.Category.callAppenders(Category.java:131)

        at org.apache.log4j.Category.log(Category.java:512)

        at callers.fully.qualified.className.methodName(FileName.java:74)

        ...

       

    
*/


  
public LocationInfo(Throwable t, String fqnOfCallingClass) {

    String s;

…

      t.printStackTrace(pw);

      s 
= sw.toString();

      sw.getBuffer().setLength(
0);

  …. 
// 这里的代码省略

  }


[
/code]

 

这里我们可以看到整体的实现思路。

首先,t.printStackTrace(pw); 获得stack trace字符串。这个t是 
new Throwable()的结果。用户程序调用Log4J方法之后,Log4J自己又进行了4次调用,然后才获得了 t = new Throwable() :

          at org.apache.log4j.PatternLayout.format(PatternLayout.java:
413)

          at org.apache.log4j.FileAppender.doAppend(FileAppender.java:
183)

        at org.apache.log4j.Category.callAppenders(Category.java:
131)

        at org.apache.log4j.Category.log(Category.java:
512)

那么,往下走4行,就可以回到用户程序本身的调用信息:

        at callers.fully.qualified.className.methodName(FileName.java:
74)

这一行里面,类名、方法名、文件名、行号等信息全有了。解析这一行,就可以获得需要的所有信息。

三、JDK1.
4 Log的相关实现
Log4J大获成功,Sun决定在JDK1.4中引入这个Log功能。

为了免去解析StackTrace字符串的麻烦,JDK1.4引入了一个新的类,StackTraceElement。

 

public final class StackTraceElement implements java.io.Serializable {

    
// Normally initialized by VM (public constructor added in 1.5)

    
private String declaringClass;

    
private String methodName;

    
private String fileName;

    
private int    lineNumber;

 

可以看到,恰好包括类名、方法名、文件名、行号等信息。

我们来看JDK1.
4 Log的相关实现。

LocationInfo.java 的infoCaller方法(推算调用者)

 

    
// Private method to infer the callers class and method names

    
private void inferCaller() {

…

            
// Get the stack trace.

            StackTraceElement stack[] 
= (new Throwable()).getStackTrace();

            
// First, search back to a method in the Logger class.

…. 
// 这里的代码省略

            
// Now search for the first frame before the "Logger" class.

            
while (ix < stack.length) {

                StackTraceElement frame 
= stack[ix];

                String cname 
= frame.getClassName();

                
if (!cname.equals("java.util.logging.Logger")) 

                        
// Weve found the relevant frame.

… 
// 这里的代码省略

            }


            
// We haven     found a suitable frame, so just punt.  This is

        
// OK as we are only committed to making a "best effort" here.

    }


 

从注释中就可以看出实现思路。过程和Log4J异曲同工。只是免去了解析字符串的麻烦。

四、Log4J 
1.3 alpha的相关实现
既然JDK1.4中引入了StackTraceElement类,Log4J也要与时俱进。LocationInfo类也有了相应的变化。

 

  
/**

     Instantiate location information based on a Throwable. We

     expect the Throwable t, to be in the format

 

       
        java.lang.Throwable

        ...

          at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)

          at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)

        at org.apache.log4j.Category.callAppenders(Category.java:131)

        at org.apache.log4j.Category.log(Category.java:512)

        at callers.fully.qualified.className.methodName(FileName.java:74)

        ...

       

 

       However, we can also deal with JIT compilers that "lose" the

       location information, especially between the parentheses.

 

    
*/


  
public LocationInfo(Throwable t, String fqnOfInvokingClass) {

    
if(PlatformInfo.hasStackTraceElement()) {

      StackTraceElementExtractor.extract(
this, t, fqnOfInvokingClass);

    }
 else {

      LegacyExtractor.extract(
this, t, fqnOfInvokingClass);  

    }


  }


 

可以看到,Log4J首先判断Java平台是否支持StackTraceElement,如果是,那么用StackTraceElementExtractor,否则使用原来的LegacyExtractor。

下面来看StackTraceElementExtractor.java

 

/**

 * A faster extractor based on StackTraceElements introduced in JDK 1.4.

 *

 * The present code uses reflection. Thus, it should compile on all platforms.

 *

 * 
@author Martin Schulz

 * 
@author Ceki Gülcü

 *

 
*/


public class StackTraceElementExtractor {

  
protected static boolean haveStackTraceElement = false;

  
private static Method getStackTrace = null;

  
private static Method getClassName = null;

  
private static Method getFileName = null;

  
private static Method getMethodName = null;

  
private static Method getLineNumber = null;

…. 
// 以下代码省略

 

可以看到,Log4J 
1.3仍然兼容JDK1.3,而且为JDK1.4也做了相应的优化。

五、JDK1.5的Thread Stack Trace
JDK1.5在Thread类里面引入了getStackTrace()和getAllStackTraces()两个方法。这下子,我们不用 (
new Throwable()).getStackTrace ();可以调用

Thread.getCurrentThread().getStackTrace()来获得当前线程的运行栈信息。不仅如此,只要权限允许,还可以获得其它线程的运行栈信息。

 

    
/**

     * Returns an array of stack trace elements representing the stack dump

     * of this thread.  This method will return a zero-length array if

     * this thread has not started or has terminated. 

     * If the returned array is of non-zero length then the first element of 

     * the array represents the top of the stack, which is the most recent

     * method invocation in the sequence.  The last element of the array

     * represents the bottom of the stack, which is the least recent method

     * invocation in the sequence.

     *

     * If there is a security manager, and this thread is not 

     * the current thread, then the security managers 

     * checkPermission method is called with a 

     * RuntimePermission("getStackTrace") permission

     * to see if its ok to get the stack trace. 

     *

     * Some virtual machines may, under some circumstances, omit one

     * or more stack frames from the stack trace.  In the extreme case,

     * a virtual machine that has no stack trace information concerning

     * this thread is permitted to return a zero-length array from this

     * method.  

     *

     * 
@return an array of StackTraceElement, 

     * each represents one stack frame.

     *

     * 
@since 1.5

     
*/


    
public StackTraceElement[] getStackTrace() {

        
if (this != Thread.currentThread()) {

            
// check for getStackTrace permission

            SecurityManager security 
= System.getSecurityManager();

            
if (security != null) {

                security.checkPermission(

                    SecurityConstants.GET_STACK_TRACE_PERMISSION);

            }


        }


 

        
if (!isAlive()) {

            
return EMPTY_STACK_TRACE;

        }


 

        Thread[] threads 
= new Thread[1];

        threads[
0] = this;

        StackTraceElement[][] result 
= dumpThreads(threads);

        
return result[0]; 

    }


 

    
/**

     * Returns a map of stack traces for all live threads.

     *

     * 
@since 1.5

     
*/


    
public static Map getAllStackTraces() {

        
// check for getStackTrace permission

        
// Get a snapshot of the list of all threads 

    }


 

六、总结
从总的发展趋势来看,JDK不仅提供越来越多、越来越强的功能,而且暴露给用户的控制方法越来越多,越来越强大。

如此一来我 自己的 实现是这样的

 

 

    static {
        p 
= new Properties();
        dbconfig 
= new Properties();
        
//Object obj = new Object();//构造一个对象,应为在 static 中无法获知当前类,用obj它的class来获得属性文件
        InputStream is = null;//obj.getClass().getResourceAsStream("DBConfig.properties");
        StackTraceElement ste[] = (new Throwable()).getStackTrace();
        
try {
            is 
= Class.forName(ste[0].getClassName()).getResourceAsStream("DBConfig.properties");
        }
 catch (ClassNotFoundException e2) {
            
// TODO 自动生成 catch 块
            e2.printStackTrace();
        }

//        for(int i=0;i<ste.length;i++){
//            System.out.println("" + ste[i].getFileName() + "  [" + ste[i].getClassName() + "]::" + ste[i].getMethodName() + "@" + ste[i].getLineNumber() + "行");
//        }
        try {
            dbconfig.load(is);
        }
 catch (IOException e1) {
            
// TODO 自动生成 catch 块
            e1.printStackTrace();
        }

        String driver 
= dbconfig.getProperty("JdbcDriverClass");
        
if(driver==null||driver.equals("")){
            driver 
= JDBC_DRIVER;
        }

        String url 
= dbconfig.getProperty("JdbcUrl");
        
if(driver==null||driver.equals("")){
            url 
= JDBC_URL;
        }

        String user 
= dbconfig.getProperty("JdbcUser");
        
if(driver==null||driver.equals("")){
            user 
= JDBC_USER;
        }

        String pwd 
= dbconfig.getProperty("JdbcPassword");
        
if(driver==null||driver.equals("")){
            pwd 
= JDBC_PWD;
        }


        p.setProperty(
"driverClassName", driver);
        p.setProperty(
"url", url);
        p.setProperty(
"password", pwd);
        p.setProperty(
"username", user);
        p.setProperty(
"maxActive", "30");
        p.setProperty(
"maxIdle", "10");
        p.setProperty(
"maxWait", "1000");
        p.setProperty(
"removeAbandoned", "false");
        p.setProperty(
"removeAbandonedTimeout", "120");
        p.setProperty(
"testOnBorrow", "true");
        p.setProperty(
"logAbandoned", "true");

        
try {
            bds 
= (BasicDataSource) BasicDataSourceFactory.createDataSource(p);
        }
 catch (Exception e) {
            
// TODO 自动生成 catch 块
            e.printStackTrace();
        }

    }
这样就实现了在静态块中访问当前类信息的方法了,也许有朋友会问,为什么不直接把当前类名传递给 Class.forName呢,的确这样是可行的,但我考虑到如果我的类名改变了呢,而且,这个类名字符串写进去就成了硬编码来,这个似乎不太好。另外,我也考虑过用过 init(String path)方法,这样更灵活,问题是这个类是个静态类,每次调用都不知道以前是否在某个地方调用过这个init 方法,当然了这个类作static类似乎不太好,因为它毕竟对不同时候应该配置也不一样。这就不讨论了,主要是学习了这个 StackTraceElement类,开拓下思维!
3D视觉入门必看:深度图、点云图、IR图、RGB图像到底有什么区别? 本文深入解析了3D视觉中深度图、点云图、IR图与RGB图像的核心区别。深度图记录像素距离,是连接2D与3D的桥梁;点云图是显式的三维坐标集合;IR图感知红外光强度;RGB图像则提供颜色纹理。理解其信息维度和应用场景,是进行机器人导航、三维重建等任务的基础。 阅读详情

相关推荐

我看MFC的过去、现在和未来

首先说句题外话,虽然我现在的“主业”是Qt,但自己扪心自问,对MFC的熟悉程度要超过Qt。正是由于有了对MFC的熟悉,才能在使用Qt时,比较清醒的认清两者的优劣之处,在此暂且不提。 这个话题也可以说是由来已久,众说纷纭,今时我也谈谈自己的感悟。 一、对MFC的总体看法 首先看看云风在其《游戏之旅-我的编程感悟》一书中对MFC的看法: “我所见到的程序员中,很多把C+

qter_wd007的专栏 6117

java static方法(单例)

1.可以直接用过类名调用 2.static在类中只存在一份副本:static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本【存放在方法区】,它当且仅当在类初次加载时会被初始化【加final和不加final的static变量初始化的位置不一样】。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。 3.static代码块在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次 4.

weixin_44911775的博客 3487

Xilinx Aurora 8B/10B IP核详解和仿真

Xilinx Aurora 8b/10b IP核的详解,以及使用与仿真示例,对IP核的配置和如何仿真有非常详细的说明,除了对IP核官方文档的内容进行了解析以外,还对GTX引脚的选择等比较容易混淆和不好理解的地方进行了说明。最后对IP核的仿真运行进行了STEP BY STEP 的说明,对仿真的结果也进行了简要的说明。 该文档对Xilinx FPGA和ZYNQ SOC下 AURORA 8B/10B IP核的使用提供了一个快速上手的指导。

weixin_43354598的博客 1万+

(四): Java中静态代码块及对象的初始化顺序

[code="java"]class Parent{ static String name = "hello"; { System.out.println("parent block"); } static { System.out.println("parent static block"); } public Parent(){ System.out...

lukuijun1981的专栏 232

德国冯哈勃 Faulhaber2342L012空心杯减速电机带编码器

为了制作平衡车,我在淘宝上面买了一个 Faulhaber2342L012空心杯减速电机电机,具体参数如下: 一:电机参数 型    号:德国冯哈勃Faulhaber带编码器空心杯减速电机2342L012  12V每分 钟 120转 工作电压: 12V 空载转速:8100RPM(转每分钟) 减速后速:120RPM(转每分钟) 直     径:30mm

u011511430的专栏 1万+

高效数据迁移:ICCAP到ADS的数据导入与导出实战指南

本文提供了从ICCAP到ADS进行高效、准确数据迁移的实战指南。针对射频与微波电路设计中的关键挑战,详细阐述了迁移前的战略规划、ICCAP数据的精细化导出(包括脚本化批处理)、ADS数据的多种导入方法(如Data Items、DML模型库及编程化API),并强调了数据完整性与准确性验证的重要性,确保模型参数和仿真结果在平台间可靠传递。

weixin_29291185的博客 133

Java 获得当前执行的类名与方法名

    System.out.println("执行" + this.getClass().getSimpleName()+ ":" + new Exception().getStackTrace()[0].getMethodName());  

alexzt的博客 3346

《谷歌数据分析方法》脑图笔记

目录壹、脑图笔记贰、《谷歌数据分析方法》脑图文稿[^1]一、 反思数据分析二、选择数据分析工具的最佳策略第一步:选择数据分析工具前要回答的3个关键问题第二步:选择数据分析工具前要问供应商的10个问题第三步:如何有效地试用数据分析工具第四步:确定合作前的协议,检查供应商的服务条款三、点击流分析的精彩世界:指标8个关键网站指标数据分析指标揭秘关键网站指标的战略性策略四、成功的关键:衡量绩效关注“少数关键指标”衡量非电子商务网站的成功衡量B2B网站五、调研和测试永不过时的3个最佳调研问题选择线上调研供应商的8个建

积跬步,慕至千里的博客 2929

java获取静态类_Java 静态方法获取当前类

Java中静态方法不依赖于具体的实例存在,所有不能直接使用this指针,需要别的方式间接的获取到类名。方法方法1:通过SecurityManager的保护方法getClassContext()private static String test1() {return new SecurityManager() {public String getClassName() {return getCla...

weixin_34462581的博客 1807

BUCK电路的EMI优化设计案例

10μH的电感以及SW铺铜面积都比较大,在保证电流能力的情况下,切掉部分SW面积,换用更小体积的小感值电感。最终结果如图14.38所示,优化SW面积和电感后,提升了10dB左右,基本满足了class 5的限值要求。如图14.36,为一个BUCK电路的LED驱动板,从原理图来看,绿色的滤波器输入地和黄色的功率地通过输入电容隔开,这样高频电流环路的噪声电流会先经过输入的陶瓷电容,但是实际的PCB布局中,可以看到输入地和高频电流环路重合,噪声可以直接耦合到输入环路上。图 14.36 一个BUCK电路的布局。

qq_43416206的博客 525

《四》:LBE,VR 大空间系列——Pico的空间扫描方式

(这里有个选项叫高精度扫描模式,这个功能在下方详细补充)系统会根据绘制的顶点,将区域分割成若干个4X4米的小方格,我们只需要根据提示,首先进入一个方格子空间内部,然后依次凝视每个区域上下左右前后六个面的小方格组,每一面4个,直至全部消失, 消失后地面会出现一个方形行走路径,我们沿着边缘正或反走一圈即可,完成后此块区域即自动消失。不过由于pico有一个高精度扫描圈,如图加粗的圆环,这个圆环的意思是在在内部的区域扫描精度较高,越远离原点的区域误差越大,所以为了更有效的利用,建议原点设置在场地中心区域。

unitygroup的博客 2888

java类的static块什么时候执行

<br />static块到底在什么时候运行的呢?如果了解JVM原理,我们可以知道,一个类的运行分为以下步骤:<br />1、装载;2、链接;3、初始化;4、初始化;5,实例化(创建新的实例)<br />实际上,static块的执行发生在“初始化”的阶段。初始化阶段,jvm主要完成对静态变量的初始化,静态块执行等工作。<br />下面我们看看执行static块的几种情况:<br />1、第一次new A()的过程会打印"";因为这个过程包括了初始化<br />2、第一次Class.forName("A")的

godwanglong的专栏 2470

【UML】第12篇 序列图(1/2)——基本概念和构成

序列图(Sequence Diagram)是一种用于显示对象之间交互的图形化表示。它描述了在特定场景下,对象之间按照时间顺序进行的消息传递和协作过程。在序列图中,对象被表示为带有垂直虚线的矩形,虚线表示对象的生命周期。对象之间的交互通过箭头表示的消息来表示,箭头从一个对象的生命线指向另一个对象的生命线,表示消息的发送和接收。

AI人人懂 3053

java static块 什么时候调用_java static代码块执行时机

之前一直认为static块是在class load的时候执行,今天在验证Spring初始化Context loader的时候,发现bean的static块并没有执行。Java代码:1 Class A{2 static{3 System.out.println("static block invoked!")4 }5 }那么static块到底在什么时候运行的呢?如果了解JVM...

weixin_42520573的博客 1077

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

java的static块执行时机

一、误区:简单认为JAVA静态代码块在类被加载时就会自动执行。证错如下:   class MyClass1 { static {//静态块 System.out.println("static block "); } } public class Main { Class[] classArray = { MyClass1.cla

berber78的专栏 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java static块 什么时候调用_java类的static块什么时候执行

java类的static块什么时候执行?很多人包括我自己,过去常常以为类是在第一次被装在的时候运行static块,其实不然。例子:Class A{static{System.out.println("static block invoked!")}}static块到底在什么时候运行的呢?如果了解JVM原理,我们可以知道,一个类的运行分为以下步骤:1、装载;2、链接;3、初始化;4、初始化;5,实例...

weixin_30946627的博客 801

Java中static块执行时机

因为在项目中遇到了static的使用,因此写一篇博客来复习巩固一下相关内容。 我们在过去的一段时间内接受的思想是:static代码块是在类加载的时候执行的。 那么看一个代码案例: public class ObjectInstance { static {//静态块 System.out.println("static block "); } } class Main { sta...

javashareauthor的博客 799

java的static块运行时机(类加载,类的加载)

一. 类加载 & 类的加载 一般认为static块是在『类加载』时期运行的。 但翻博客看到有人认为这句话是错的,作为一个初学者一下子不知道哪个是正确的。花时间整理了一遍这部分内容。 先说结论:这句话其实没什么问题,但很多人可能由于英文翻译导致的问题而产生误会。 这里的『类加载』其实指的是完整的『类加载』过程,而不是『类的加载』。 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤。我

不愿透露姓名的马建国的博客 2864

java类中的static块_Java中static块执行时机

Java中static块执行时机演示例子在使用static进行初始化的操作,怎么也执行不了!代码如下:public class StaticDemo {public static final String INIT = "init";static {System.out.println("------StaticDemo----");}}public class TestStatic {publi...

weixin_27972919的博客 278

static静态方法内获取当前类

前景:最近web项目在实现一个在java文件中读取项目目录webcontent下的某一个资源文件,在static方法中需要获取资源文件的路径,因此需要根据当前的class去获取到webcontent的路径。 众所周知,static修饰的方法中不能使用this关键字,因此不能再static方法中使用this.getClass()获取当前文件的class,因此换一种思路,编写一个静态方法,里面定义一

qq_26702601的博客 5418

java static块的执行时机

总的来说,`static`块的主要作用是在类加载时执行静态初始化操作,例如初始化静态变量、加载静态资源等。2. **加载顺序**:在类加载时,`static`块会按照它们在类中出现的顺序依次执行。在Java中,`static`块是用来初始化类的静态变量或执行静态操作的代码块。4. **优先级高于实例初始化块**:`static`块的执行优先级高于实例初始化块。即`static`块先于实例初始化块执行。3. **只执行一次**:`static`块只会在类加载时执行一次,无论这个类被实例化多少次。

weixin_37841024的博客 742

static块

一、static块什么时候执行 在Java中,一个类运行时,JVM会做这几件事:     1.类加载     2.连接(验证,准备,解析)     3.初始化     4.实例化(使用,卸载) 而static代码块中的语句就在初始化时执行。事实上,在初始化阶段,JVM主要就是完成静态块语句的执行以及静态变量的初始化这样的工作。 二、static块的特点    (1)

AXDY_Z的博客 483

java类运行以及static块的执行顺序

一、java类的static块什么时候执行 如果了解JVM原理,我们可以知道,一个类的运行分为以下步骤: 1、装载;2、链接;3、初始化;4、初始化;5,实例化(创建新的实例) 实际上,static块的执行发生在“初始化”的阶段。初始化阶段,jvm主要完成对静态变量的初始化,静态块执行等工作。 下面我们看看执行static块的几种情况: 1、第一次new A()的过程会打印"";因为这个

技术人宝哥 1660

static代码块何时执行

之前一直纠结类中static代码块什么时候执行,很多java开发者都回答在类装载时执行,也有人认为是在类第一次被使用时执行,直到看到了这篇文章: http://www.cnblogs.com/ivanfu/archive/2012/02/12/2347817.html 先转载过来 之前一直认为static块是在class load的时候执行,今天在验证Spring初始化Context l

BranStark的专栏 3403

Java 类中的static块

原文地址:http://mht.iteye.com/blog/170350 Java 程序中时常用些 static {} 这样的结构。  这样的结构叫 static块 ,一般是一个类初始化时运行的代码。 注意,是类的初始化,不是对象的初始化。  也就是你在定义对象是,它运行的初始化代码,并且只有第一次定义时才运行。之后就不再运行初始化了。  一个类中可以可以有很多sta

WJ S的专栏 1637
上一篇: 将Java程序转换为Windows服务 作者:IT168 seasky 2007-09-19
下一篇: Log4J 最佳实践之全能配置文件
javaokay
博客等级 码龄20年 6粉丝 13原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值