首先要说明的是,java里不能直接使用synchronized声明一个变量,而是使用synchronized去修饰一个代码块或一个方法.\x0d\x0a\x0d\x0a详细说明如下:\x0d\x0a\x0d\x0a synchronized用来修饰一个方法或者一个代码块,它用来保证在同一时刻最多只有一个线程执行该段代码.\x0d\x0a 第一段:当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.\x0d\x0a 第二段:然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块.\x0d\x0a 第三段:尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞.\x0d\x0a 第四段:第三个例子同样适用其它同步代码块.也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁.结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞.\x0d\x0a 第五段:以上规则对其它对象锁同样适用.\x0d\x0a\x0d\x0a示例代码:\x0d\x0apublic class Thread1 implements Runnable { \x0d\x0a public void run() { \x0d\x0a synchronized(this) { \x0d\x0a for (int i = 0; i
类型 变量名[=初值] [,变量名[=初值].......
string s="",b=""; 中间,表示连续申明变量,都是最前面的类型.
第一种方法是正确的,没事.在java中用char的默认编码是unicode码,想知道unicode码是多少~就把char+1赋值给int~得到的值减去1~~就是unicode的数字代码了
个人的总结
①. 静态变量只有一份被类的所有实例共享
引用
Java静态变量的初始化(static块的本质)
在网上看到了下面的一段代码:
① public class Test {
①.0. }
Java类中可以定义一个static块,用于静态变量的初始化.如:
public class Test { public static int _i; static { _i = 10; } }
当然最常用的初始化静态变量的操作是在声明变量时直接进行赋值操作.如:
public class Test { public static int _i = 10; }
那么上述两例在本质上有什么区别吗?回答是没有区别.两例代码编译之后的字节码完全一致,通过 "javap -c"查看到的字节码如下:
public class Test extends java.lang.Object{
public static int _i;
public Test();
Code:
0: aload_0
①.: invokespecial #1; //Method java/lang/Object."init":()V
static {};
0: bipush 10
}
通过字节码还可以看出,当类的定义中不含有static块时,编译器会为该类提供一个默认的static块.当然这是在含有静态变量初始化操作的前 提下.如果静态变量没有初始化操作,则编译器不会为之提供默认的static块.如:
public class Test { public static int _i; }
其字节码的表现形式为:
由于静态变量是通过赋值操作进行初始化的,所以呢可以通过静态函数返回值的方式为其初始化.如:
public class Test { public static int _i = init(); private static int init() { return 10; } }
其本质与下面的代码相同:
public class Test { public static int _i; static { _i = init(); } private static int init() { return 10; } }
类定义中可以存在多个static块吗?回答是可以.如:
①.0. static {
此类编译之后的字节码为:
public static void main(java.lang.String[]);
0: return
①.0: return
观察static{}部分可以看出,上例的代码与下面的代码效果一致:
①.0. }
①.1. }
此例可以证明,不仅类定义中可以有多个static块,而且在编译时编译器会将多个static块按照代码的前后位置重新组合成一个static 块.
静态变量存放在常量池之中.如何证明呢?如:
使用"javap -c -verbose"查看其字节码的内容如下:
public class Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
Constant pool:
const #10 = Asciz LineNumberTable;
const #11 = Asciz clinit;
{
Stack=1, Locals=1, Args_size=1
LineNumberTable:
Stack=1, Locals=0, Args_size=0
* 静态变量的声明与初始化是两个不同的操作;
* 静态变量的声明在编译时已经明确了内存的位置.
如:
上述代码的本质可以视为:
public class Test { // 静态变量的声明 public static int _i; // 静态变量的初始化 static { _i = 10; } }
由于静态变量的声明在编译时已经明确,所以静态变量的声明与初始化在编码顺序上可以颠倒.也就是说可以先编写初始化的代码,再编写声明代码.如:
public class Test { // 静态变量的初始化 static { _i = 10; } // 静态变量的声明 public static int _i; }
对初始问题的解答
解答了上述三个问题,让我们再来看看开篇提到的问题.代码如下:
其本质可以用下面的代码表示:
①.0. public static void main(String[] args) {
①.1. System.out.println(_i);
再简化一下,可以表示为:
①.0. System.out.println(_i);
①.1. }
至此,代码已经明确告诉我们打印结果是什么了!