静态代码块的加载与执行

By heiry on 2019-04-17 [ in 技术 ]

java中的静态代码块,在被载入内存的时候被执行,而且只执行一次,正因如此,某些场景下我们可以用静态代码块实现单例模式。但是对于静态代码块的执行顺序,如果没好好理解,就容易掉坑。

静态代码块装载时才执行。类在第一次被使用的时候才被装载,而不是程序启动时就装载所有的类,因此含静态代码块的所在类被装载时静态代码块才会运行。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
}
static {
System.out.println("this static area run auto");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); } static { System.out.println("this static area run auto"); } }
public class StaticCodeTest { 
        public static void main(String [] args){ 
        System.out.println("main fun running");
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

以上代码运行结果如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
this static area run auto main fun running
this static area run auto
main fun running

StaticCodeTest类在载入时自动运行了静态代码块,而且静态代码块优先于main方法执行。

在上述的代码基础上,我们加入两个类

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块1被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块1被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}

运行结果如下

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
this static area run auto main fun running
this static area run auto
main fun running

可见,如果静态代码块所在类没有被装载,静态代码块是不会自动运行的。

创建新增两个类的对象,代码及运行结果如下

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
StaticAreaDemo_2 p2 = new StaticAreaDemo_2();
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); StaticAreaDemo_1 p1 = new StaticAreaDemo_1(); StaticAreaDemo_2 p2 = new StaticAreaDemo_2(); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
    StaticAreaDemo_2 p2 = new StaticAreaDemo_2();
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
来自www.mosang.net的静态代码块被执行
this static area run auto main fun running 来自blog.mosang.net的静态代码块被执行 来自www.mosang.net的静态代码块被执行
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
来自www.mosang.net的静态代码块被执行

以上可看出,装载StaticAreaDemo_1和StaticAreaDemo_2,其中的代码块执行,但是并没有优先于main方法执行。

上述代码更改为同一个类创建两个对象:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
StaticAreaDemo_1 p2 = new StaticAreaDemo_1();
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); StaticAreaDemo_1 p1 = new StaticAreaDemo_1(); StaticAreaDemo_1 p2 = new StaticAreaDemo_1(); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
    StaticAreaDemo_1 p2 = new StaticAreaDemo_1();
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}

运行结果:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
this static area run auto main fun running 来自blog.mosang.net的静态代码块被执行
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行

可见,尽管创建了两个对象,静态代码块只执行了一次。

>> 阅读全文  >>

996,一场公然的资本嗜血

By heiry on 2019-04-15 [ in 管理, 随写 ]

有赞年会的996大福利横空出世,加上马云员工福气论黄袍加身,刘强东力推996昭告淘汰三类人,掀起了2019IT行业的血雨腥风。

我非弱者思维患者,身处这个行业多年,基层干过,中层体验过,高层做过,怎可不知站在各个角度考虑问题?

在创业者、高管、老板的角度,或者在公司发表意见,吾等一定高呼马云万岁,高举有赞伟大旗帜,团结在英明的公司董事会周围,坚决贯彻996到每个工作岗位,鼓掌。。。 因为我知道,这样我的收益才会最大化。

而面对一个个眼中无神的程序员、设计师,我只想说,只懂得拿时间换钱,换来的将是悲哀,这样所谓的奋斗将置你落于尘埃。

前些天看阮一峰的一篇文章,觉得很有意思,也与这个话题颇为贴切,转来分享之,原文如下:
—————————————————————————————————————————————————-

前几天,我听一个广播节目。主持人问,现在很多人开网约车,这样能赚多少钱,能够赚到大钱吗?

这个问题很容易回答,答案就是不能。

出租车司机的收入,主要由营业时间的长短决定。基本上,一天开12个小时,就是比开6个小时,收入高出一倍。每天只有24个小时,因此收入存在上限,不可能偏离平均水平很远。 出租车是”时间换收入”的典型行业,投入的时间越多,收入越高,在家休息就没收入。

很多行业都属于”时间换收入”,所有此类行业都赚不到大钱。因为你能用来交换的时间是有限的,而且进入中年以后,你就拿不出更多的时间来交换。开出租车赚零花钱,或者作为短期过渡,这是没问题的,但作为终身职业是很糟糕的。

我觉得,越来越多的程序员正在落入这个陷井,用编码的时间换取收入。只有不停地做项目,才能拿到钱。项目做得越多,收入越高。这个项目开发完了,公司又让他去干下一个项目。 忙了好几年,项目完成了一大堆,但是自己什么也没留下,以后的收入还要取决于从零开始的新项目。这样的话,你跟出租车司机有何两样,哪一天你不写代码了,不是照样没收入。

那些赚到大钱的人,没有一个是靠时间换取收入的。他们要么通过积累资产致富,要么购买他人的时间,为自己创造财富。

你应该警惕,不要落入”时间换取收入”的陷井,不要只顾着为别人生产代码,而要注意积累自己的资产,以及适时开展属于自己的业务。

—————————————————————————————————————————————————-

(更多…)

>> 阅读全文  >>

委托在异步模式下的运用

By heiry on 2019-04-14 [ in 技术 ]

异步模式下,获得数据的时间点通常具有不确定性,在封装异步方法时,通常要用到委托来达到返回数据和操作数据的目的。

异步请求中委托一般通过高阶函数来实现(函数作为参数传递或函数作为返回值返回)。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var mytest = function(vars){
console.log(vars+"作为参数传入");
}
function showDemo(foo) {
foo("demo:");
}
showDemo(mytest);
var mytest = function(vars){ console.log(vars+"作为参数传入"); } function showDemo(foo) { foo("demo:"); } showDemo(mytest);
var mytest = function(vars){
    console.log(vars+"作为参数传入");
}
function showDemo(foo) {
foo("demo:");
}

showDemo(mytest);

通过委托实现异步请求方法的封装:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
var getInfo = function(url,articleId,callBack){
$.ajax(url+"?id="+articleId,function(data){
if(typeof callBack == "function"){
callBack(data);
}
});
}
getInfo("https://blog.mosang.net",2856,function(data){console.log(data)});
var getInfo = function(url,articleId,callBack){ $.ajax(url+"?id="+articleId,function(data){ if(typeof callBack == "function"){ callBack(data); } }); } getInfo("https://blog.mosang.net",2856,function(data){console.log(data)});
var getInfo = function(url,articleId,callBack){
    $.ajax(url+"?id="+articleId,function(data){
        if(typeof callBack == "function"){
            callBack(data);
        }
    });
}
getInfo("https://blog.mosang.net",2856,function(data){console.log(data)});

 

 

 

>> 阅读全文  >>

Java中包(Package)的深入理解

By heiry on 2019-04-12 [ in 技术 ]

被一个java新人请教关于包的理解和使用,想起了自己当年刚学java时候的体会。

包-Pakage,概念理解和使用不难,但对于刚接触java的人而言,有点抽象和不解。

人人皆知,java中的包主要用于解决类的重名问题,类似于XML、C#,PHP等命名空间的概念,但与这些语言有所区别,它既有命名空间的逻辑分割又有物理上的实际目录划分。

一.使用

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
pakage mosang.tech //表明A.java 源文件中,所有类都位于mosang.tech包中
public class A{
public static void main(String [] args){
new B().showInfo();
}
}
class B{
public showInfo(){
System.out.print("this a method of how to using pakage");
}
}
pakage mosang.tech //表明A.java 源文件中,所有类都位于mosang.tech包中 public class A{ public static void main(String [] args){ new B().showInfo(); } } class B{ public showInfo(){ System.out.print("this a method of how to using pakage"); } }
pakage mosang.tech //表明A.java 源文件中,所有类都位于mosang.tech包中
public class A{
public static void main(String [] args){
new B().showInfo();
}
}
class B{
public showInfo(){
System.out.print("this a method of how to using pakage");
}
}

假设我们已经将classpath设置为A.java所在的目录:

上述代码运行编译后会自动生成mosang/tech文件夹,同时得到一个B.class字节码文件位于tech文件夹中

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
javac -d . A.java
javac -d . A.java
javac -d . A.java

这时候,运行B.class文件需要带完整包名,哪怕我们在命令行窗口进入了mosang/tech目录。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
java mosang.tech.B
java mosang.tech.B
java mosang.tech.B

这就是包的基本用法。

二.陷阱一:类名的使用

如果我们在命令行进入mosang/tech目录运行B.class,编译器会提示找不到文件,因为类的名字已是mosang.tech.B而不是B。

二.陷阱二:classpath路径与包名

JVM在加载带包名的路径时候,会先到classpath指定的目录,再从此按照包名结构去查找class文件。如果我们在命令行进入mosang/tech目录运行mosang.tech.B,同样会报错,因为此时的完整路径变成了classpath/mosang/tech/mosang/tech/B.class

三.陷阱三:包名与目录名

java中,包名必须经过程序中pakage语句来指定,而不是靠目录结构来指定的,是先有了包名,才需要相应的目录结构。我们来做个试验:

删除原生成的B.lass文件,在源代码A.java中,将pakage语句注释掉,重新编译得到B.class,将B.class拷贝到mosang/tech文件夹中,classpath目录下运行mosang.tech.B,会出错,因为此时的类名是B而不是mosang.tech.B。

所以,我们常常误以为把一个类文件放到了一个目录中,这个目录结构就自然成了包名,这就大错特错了。这点很多人包含有多年java经验的人都会犯错,绝大部分新手更是有这种自以为是理解。

 

 

 

>> 阅读全文  >>

AJAX跨域与URI大小写问题

By heiry on 2019-03-27 [ in 技术 ]

以前解决过很多异步请求跨域的问题,自认为不会有什么难点,可今天调试一个项目API的时候遇到了之前没遇到的问题,弄了好久才解决,记录如下:

项目中涉及一个主域(以www.abc.com表示),子域(以s.abc.com表示),子域控制器s.abc.com/Action向主域www.abc.com/Reply发异步POST请求,www.abc.com/Reply发出Header参数“Access-Control-Allow-Origin:http://s.abc.com““Access-Control-Allow-Methods:POST”,按理说这应该没什么问题了,但问题来了:
1. 直接访问通过URL:www.abc.com/Reply访问,可以看到添加的“Access-Control-Allow-Origin“等响应头,也能正常传递JSON,如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: http://s.abc.com
Access-Control-Expose-Headers: Authorization
Content-Encoding: gzip
Content-Length: 138
Content-Type: text/json; charset=utf-8
Date: Wed, 27 Mar 2019 07:03:09 GMT
Server: Tengine
Vary: Accept-Encoding
Access-Control-Allow-Methods: POST Access-Control-Allow-Origin: http://s.abc.com Access-Control-Expose-Headers: Authorization Content-Encoding: gzip Content-Length: 138 Content-Type: text/json; charset=utf-8 Date: Wed, 27 Mar 2019 07:03:09 GMT Server: Tengine Vary: Accept-Encoding
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: http://s.abc.com
Access-Control-Expose-Headers: Authorization
Content-Encoding: gzip
Content-Length: 138
Content-Type: text/json; charset=utf-8
Date: Wed, 27 Mar 2019 07:03:09 GMT
Server: Tengine
Vary: Accept-Encoding

2. 但通过子域的AJAX请求,死活就得不到添加的Headers参数,FF及Chrome均提示提示同源错误“原因:头缺少 ‘Access-Control-Allow-Origin’”,明明已经设置,就是没有传递,而之前做的一个接口几乎代码一样,但却能正常返回值,确实让人百思不得其解。
无奈之下,只能检查服务器设置,发现URLrewrite有如下规则:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<rule name="LowerCaseRule1" stopProcessing="true">
<match url="[A-Z]" ignoreCase="false" />
<action type="Redirect" url="{ToLower:{URL}}" />
</rule>
<rule name="LowerCaseRule1" stopProcessing="true"> <match url="[A-Z]" ignoreCase="false" /> <action type="Redirect" url="{ToLower:{URL}}" /> </rule>
<rule name="LowerCaseRule1" stopProcessing="true">
                    <match url="[A-Z]" ignoreCase="false" />
                    <action type="Redirect" url="{ToLower:{URL}}" />
</rule>

 

恍然大悟!

这个是SEO常设规则,用来规避因为URL大小写而带来搜索引擎识别为不同站点的问题,而项目很多CLASS命名都根据大小驼峰规则,Controls也是大小混写,这条重写规则强制将文件名小写返回,而AJAX请求则认为是两个不同请求,导致Headers参数无法正常接收。

取消此规则,问题解决。

>> 阅读全文  >>

jquery $().val的bug

By heiry on 2019-01-31 [ in 技术 ]

近来研究一些开源的前端框架,重拾js,发现一个奇怪问题:
input如果设置为display:none,那么通过$(“#id”).val(“value”);方式赋值,无论是chrome、firefox还是IE都是传值方式失效。
改用$(“#id”).attr(“value”,”value”);却又可以
但是如果设置type=”hidden”,同样使用$(“#id”).val(“value”);方式赋值却又可以。

>> 阅读全文  >>

被深深感染的唢呐声

By heiry on 2018-06-16 [ in 生活, 随写 ]

激情、技术、美感,让一个完全不懂音乐的外行都感受到了。

——刘英大师唢呐演奏

>> 阅读全文  >>


© 2009-2024 MOSANG.NET DESIGNED BY HEIRY