- 浏览: 173334 次
- 性别:
- 来自: 宁波
文章分类
- 全部博客 (113)
- EJB3.0 (1)
- Spring+Hibernate+Struts2 (7)
- 杂谈 (27)
- ExtJs2.2 (1)
- 设计模式 (1)
- JBoss Seam (0)
- 以前在学校里学习的笔记 (3)
- 我的智能手机研究文章 (2)
- DIV+CSS美化页面 (6)
- javascript (7)
- POI操作 (2)
- 数据库 (8)
- Tomcat服务器 (2)
- 测试 (3)
- 水区 (5)
- c++ (1)
- 工作流 (0)
- osg (0)
- JS技术 (2)
- ubuntu linux (3)
- svg (1)
- android (17)
- PHP (1)
- webservise (1)
- java (1)
- mongdb (0)
最新评论
-
flytosea:
如果LIB包建立在外面的话,maven不能把jar一起打包
maven 不建立仓库直接加入直接的jar -
javaAlpha:
楼主 总结的太全了。
CSS兼容IE6,IE7,FF的技巧
JAVA的基础笔记
myeclipse 快捷键设置
== 比较内存地址
equals比较内容
从 Object层次来说 ,==与equals是相同的 ,都比较内存地址 ,也就是说,都是比较两耳光引用是否指向同一个对象,是则返回true。否则 返回false。
很多类Overwirte了 equals方法,最最典型是String类
Java的专门用语:
简单(Simple)
安全(Secure)
可移植(Portable)
面向对象(Object—oriented)
健壮(Robust)
多线程(Multithreaded)
体系结构中立(Architectrure)
解释执行(Interpreted)
高性能(Higt performanace)
分布式(Distributed)
动态(Dynamic)
Java语言一共使用了48个保留关键字,他们主要可以分为如下几类。
+访问控制
private 私有, protected 保护, public 共享.
+类、方法和变量修饰符
abstract 摘要, class 类, extends 扩允,
final 结局, implements 工具, interface 接口,
native 本地, new 新创建, static 静态,
strictfp, 精确浮点 synchronized 同步,transient 短暂,
volatile 易失.
+程序控制语句
break, continue, return, do, while, if, else
for, instanceof, switch, case,default,
+错误处理
catch 捕获, finally 最后, throw 投试,
throws 投试, try 尝试
+包相关
import 输入, package 包.
+基本类型
boolean 布尔型, byte 字节型, char 字符型, double 双精度,
float 浮点, int 整型, long 长整型, short 短整型
+变量引用:
super 特殊, this 这个, void 无值
除了这48个关键字以外,还有3个语法保留字:
null 空, true 真, false 假.
关键字 错误处理 assert :计算条件表达式,以验证程序员的假设
java 位操作符:
取反:~x
与操作:AND
x & y
或操作:OR
x | y
异或操作:XOR
x ^ y
左移操作:Shift left
x << y
将x左移y位,移动过程中,高位会丢失
有符号数右移操作:Shift Right - Signed
x >> y
无符号数右移:Shift Right - Unsigned
x >>> y
例子:
下面的例子显示如何将一个int数组通过移位操作压缩到一个int内保存,其原理是在java语言中,int类型使用4 bytes来保存,因此对于需要压缩的int数组,其中的每一个int值的大小不能超过255(2的8次方-1),因此这只是一个实例:
int [] aRGB = {0x56, 0x78, 0x9A, 0xBC}; // 是用16进制保存的4种颜色值
int color_val = aRGB[3];
color_val = color_val | (aRGB[2] <<; // 为了压缩,需要放置到color_val值的第二个字节位置上:将aRGB[2] 左移到第二个byte,同时与color_val进行或操作,下面同理
color_val = color_val | (aRGB[1] << 16);
color_val = color_val | (aRBG[0] << 24);
操作完的结果是56 78 9A BC
如果要从colorVal 还原为int数组,或者得到数组中的某个值,只需要对colorVal 进行相应的右移操作即可:
位运算符功能
~ 按位非(NOT)
取反
00101010
11010101
& 按位与(AND)
如果两个操作都是1,则结果为1。在所有其他情况下的结果均为0。
00101010 42
& 00001111 15
-----------------
00001010 10
| 按位或(OR)
如果两个操作数中有一位是1,则结果为1。
00101010 42
| 00001111 15
-----------------
00101111 47
^ 按位异或(xor)
如果两个操作数中有一个是1,则结果就是1,否者是0.
00101010 42
^ 00001111 15
-----------------
00100101 37
>> 向右移位
>>> 向右移位,左边空出的位以0填充
<< 向左移位
&= 按位与并赋值
|= 按位或并赋值
^= 按位异或并赋值
>>= 向右移位并赋值
>>>= 向右移位并赋值,左边空出的位以0填充
<<= 向左移位并赋值
声明为static的方法有几条限制:
它们仅可以调用其他的static方法.
它们只能访问static数据.
它们不能以任何方式引用this和super.
Varagrs:变长参数
两种方法处理变长参数:
1.如果参数否认最大数目不大于已知,则可以为该方法可能被调用的每一种方式创建去重载的版本。
2当参数的最大数目比较大而且不可知的时候,可将这些参数置于一个数组中,然后加数组传递给方法。
static void vaTest(int ... v) 一个变长参数由三个句点(...)来指定。
来代替一个数组,...语法只是告诉编译器将使用可变数目的参数,而这些参数将存储到一个通过v引用的数组中。
关键词final有三个用途
它可用于创建一个已命名常量的等价物,final的其他两个用法是用于继承的
使用final来阻止重写
导入包
警告 星号形式可能会增加编译时间,特别是在导入几个大包时更是如此,因此一般显示的命名想要使用的类而不是导入整个包,但是星形式对运行时的性能和类的大小却没有什么大的影响。
Threads线程
synchronized ,volatile 两个关键字
当多个线程访问同一个数据项(如静态字段、可全局访问对象的实例字段或共享集合),可以用synchronized ,volatile两个关键字
来实现这个目的。
线程的生命:
创建线程:每个Java程序至少包含一个线程-主线程。其他的线程都是通过Thread构造器或实例化继承类Thread的类来创建的。
创建线程和启动线程并不相同:一个对象拥有一个线程,必须提供一个启动该线程的start()或init()方法,而不是从构造器中启动它。
结束线程:
线程会以以下三种方式之一结束
线程到达其run()方法的末尾。
线程抛出一个未捕获到的Exception或Error。
另一个线程调用一个放弃的stop()方法。弃用是指这些方法仍然存在,但是吧 应该在新代码中使用它们,
并且应该尽量从现有代码中除去它们。
当程序中的搜游程序都完成时,程序就退出了 。
加入线程
调度
休眠
sleep()方法,当线程进入等待状态,直到过一段指定时间,或者知道另一个线程对当前线程的Thread对象调用了
Thread.interrupt(),中断了线程,线程休眠时会抛出InterruptedException,可以知道线程事中断唤醒的,不必查看计时器是否过期。
Thread.yield()方法就像Thread.sleep()一样,不能引起休眠,而只是暂停当前线程片刻,这样其他的线程就可以运行。
当较高优先级的线程调用Thread.yield()时,较低优先级的线程就不会运行。
守护程序线程
垃圾收集线程和由jvm创建的其他线程等系统线程称作为守护程序线程。
可以通过Thread.setDaemon() 方法来知名摸个线程是守护程序线程
TimerTask线程被标记成守护程序线程
线程间共享数据最简单的形式是:轮询共享变量以查看另一个线程是否已经完成执行某项任务。
存在于同一个内存空间中的所有线程,访问共享变量(静态或实例字段),线程就可以方便的交换数据,但是线程还必须确保他们以受控的方式访问共享变量,以免他们互相干扰对方的更改。
Synchronized有两个重要的含义,他确保了一次只有一个线程可以执行难代码的受保护部分(互斥,mutual exclusion 或者说 mutex),而且它却确保了一个线程更改的数据对于其他线程是可见的(更改的可见性)。
监视器monitor java 锁定合并了一种互斥形式。锁用于保护代码块或整个方法
使用HashMap以线程安全的方式提高高速缓存。
可见性同步的基本规则是在以下情况中必须同步:
读取上一次可能是有另一个线程写入的变量
写入下一次可能有另一个线程读取的变量
1.有静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
2.访问final字段时
3.在创建线程之前创建对象时
4.线程可以看见它将要处理的对象时
以上4点不需要同步
同步准则
使代码块保持简短。不要阻塞。在持有锁的时候,不要对其他对象调用方法。
wait()、notify() 和 notifyAll() 方法
深拷贝(deep clone)与浅拷贝(shallow clone)
浅复制与深复制概念
浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,
而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复
制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆):被复制对象的所有变量都含有与原来的对象相同的值,
除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过
的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制
的对象所引用的对象都复制了一遍。
Java的clone()方法【定义在Object类中】
clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x
克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()
克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
Java中对象的克隆
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。不实现Cloneable接口会出现CloneNotSupportedException异常
说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?
在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,
并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
②继承自java.lang.Object类的clone()方法是浅复制
利用序列化来做深复制
把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫
做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而原
对象仍然存在于JVM里面。
在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实
际上只是对象的一个拷贝)写到一个流里,再从流里读出来,便可以重建对象。这样做的前
提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可
串行化的对象可否设成transient,从而将之排除在复制过程之外。
注意:Cloneable与Serializable都是marker Interface,也就是说他们只是一个标识接口,
没有定义任何方法。
关于实现Serializable接口的类中的serialVersionUID问题
当一个类实现了Serializable接口时,表明该类可被序列化,这个时候Eclipse会要求你为该
类定义一个字段,该字段名字为serialVersionUID,类型为long,提示信息如下:
你可以随便写一个,在Eclipse中它替你生成一个,有两种生成方式: 一个是默认的1L,比如:
private static final long serialVersionUID = 1L; 一个是根据类名、接口名、成员方法及
属性等来生成一个64位的哈希字段,
比如:private static final long serialVersionUID = 8940196742313994740L;之类的。
当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个提
示功能告诉你去定义之。 在Eclipse中点击类中warning的图标一下【即那个黄色的图标】,
Eclipse就会自动给定两种生成的方式,如上面所述。如果不想定义它,在Eclipse的设置中也
可以把它关掉的,设置如下
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems 将Serializable class without serialVersionUID的
warning改成ignore即可。
如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了
Serializable这个接口的话,如果没有加入serialVersionUID,Eclipse都会给你warning提示,
这个serialVersionUID为了让该类别Serializable向后兼容。
如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),
当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。 但当serialVersionUID
相同时,它就会将不一样的field以type的缺省值Deserialize,这个可以避开不兼容性的问题。
volatile的用法
一个volatile(中文意思是“可变的、不稳定的”)
volatile关键字有什么用?
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;
一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
ArrayList ,linkedList,Vector三点的区别
1.ArrayList 底层实际是采用数组实现的(并且该数组的类型都是继承Object类型的)
2.如果是JDK6的话,采用Arrays.of()方法来生成一个新的数组,如果是JDK5.0的话使用System.arraycopy方法
3.List list=new ArrayList();时,底层会生成一个长度为10的数组来保存存放所需要的对象。
4.对于ArrayList与Vector来说,底层都是采用数组的方法来实现的(该数组是一个Object类型的数组)
5.对于ArrayList,所有的方法都不是同步的,对于Vector,大部分public的方法都是同步的。
6.对于ArrayList,查找速度非常快,增加和删除 操作非常慢,(本质上是由数组的特性来决定的)
7.对于LinkedList,查找速度非常慢,增加和删除 操作非常快,(本质上是由双向循环链表的特点来决定的)
Reflection中包含了两种基本的技术:探索和按名称使用。以下是对两种方法的描述:
探索指采用一个对象或类,并发现其成员、超类、实现的接口,然后尽可能地使用被发现的元素。
按名字使用指以一个元素的符号名开始,并使用已命名的元素。
通常,探索方法以一个对象开始,并通过调用Object.getClass()方法获得对象的类。类对象有很多方法发现类的内容。以下是部分方法:
getMethods():返回一组表示类或接口的所有公共方法的方法对象数组。
getConstructors():返回一组表示类的所有公共构造器的构造器对象数组。
getFields():返回一组表示类或接口所有公共字段的字段对象数组。
getClasses():返回一组表示所有属于类或接口的公共类和接口(例如,内部类)的类对象数组。
getSuperclass():返回表示类或接口的超类的类对象(接口返回为空值)。
getInterfaces():返回一组表示类或接口执行的所有接口的类对象数组。
你可以通过探索,即应用类字面(如MyClass.class)或使用类名(如Class.forName("mypackage.MyClass"))获得类对象。有了类对象,成员对象方法、构造器或字段可以通过使用成员的符号名获得。以下是最重要的一些技术:
getMethod("methodName", Class...):返回表示接受类参数指定参数的类或接口中名为“methodName”的公共方法的方法对象。
getConstructor(Class...):返回表示接受类参数指定参数的类公共构造器的构造器对象。
getField("fieldName"):返回表示类或接口中名为“fieldname”的公共字段的字段对象。
你可以使用Method、Constructor和Field(字段)对象动态地访问类表示成员。例如:
Field.get(Object):返回一个包含输入get()对象实例的字段值对象。(如果字段对象表示静态字段,那么对象参数便被忽略,也可能为空。)
Method.invoke(Object, Object...):返回一个包含为输入invoke()的第一个对象参数实例调用方法的结果的对象。其余对象参数被传递给输入方法。(如果方法对象表示一个静态方法,那么第一个对象参数便被忽略,也可能为空。)
Constructor.newInstance(Object...):返回调用构造器的新对象实例。对象参数输入构造器。(注意类的无参数构造器也可以通过newInstance()被调用。)
创建数组和代理类
java.lang.reflect包提供一个数组,其中包含了可创建和操控数组对象的静态方法。从J2SE 1.3开始,java.lang.reflect包还提供了一个代理类,它支持动态创建用来实现指定接口的代理类。
代理类的执行由执行InvocationHandler接口的一个补充对象完成。代理对象的每个调用方法调用InvocationHandler的方法调用(对象、方法、对象[])——第一参数是代理对象,第二参数是表示代理所执行接口的方法的方法对象,而第三参数是输入接口方法的参数数组。invoke()方法返回一个对象结果,其中包含返回调用代理接口方法的代码的结果。
myeclipse 快捷键设置
Context insensitive completion Ctrl+Space Content Assist Alt+/
== 比较内存地址
equals比较内容
从 Object层次来说 ,==与equals是相同的 ,都比较内存地址 ,也就是说,都是比较两耳光引用是否指向同一个对象,是则返回true。否则 返回false。
很多类Overwirte了 equals方法,最最典型是String类
Java的专门用语:
简单(Simple)
安全(Secure)
可移植(Portable)
面向对象(Object—oriented)
健壮(Robust)
多线程(Multithreaded)
体系结构中立(Architectrure)
解释执行(Interpreted)
高性能(Higt performanace)
分布式(Distributed)
动态(Dynamic)
Java语言一共使用了48个保留关键字,他们主要可以分为如下几类。
+访问控制
private 私有, protected 保护, public 共享.
+类、方法和变量修饰符
abstract 摘要, class 类, extends 扩允,
final 结局, implements 工具, interface 接口,
native 本地, new 新创建, static 静态,
strictfp, 精确浮点 synchronized 同步,transient 短暂,
volatile 易失.
+程序控制语句
break, continue, return, do, while, if, else
for, instanceof, switch, case,default,
+错误处理
catch 捕获, finally 最后, throw 投试,
throws 投试, try 尝试
+包相关
import 输入, package 包.
+基本类型
boolean 布尔型, byte 字节型, char 字符型, double 双精度,
float 浮点, int 整型, long 长整型, short 短整型
+变量引用:
super 特殊, this 这个, void 无值
除了这48个关键字以外,还有3个语法保留字:
null 空, true 真, false 假.
关键字 错误处理 assert :计算条件表达式,以验证程序员的假设
java 位操作符:
取反:~x
- flips each bit to the opposite value.
与操作:AND
x & y
- AND operation between the corresponding bits in x and y.
或操作:OR
x | y
- OR operation between the corresponding bits in x and y.
异或操作:XOR
x ^ y
- XOR operation between the corresponding bits in x and y.
左移操作:Shift left
x << y
- shifts x to the left by y bits. The high order bits are lost while zeros fill the right bits.
将x左移y位,移动过程中,高位会丢失
有符号数右移操作:Shift Right - Signed
x >> y
- shifts x to the right by y bits. The low order bits are lost while the sign bit value (0 for positive numbers, 1 for negative) fills in the left bits.
无符号数右移:Shift Right - Unsigned
x >>> y
- shifts x to the right by y bits. The low order bits are lost while zeros fill in the left bits regardless of the sign.
例子:
下面的例子显示如何将一个int数组通过移位操作压缩到一个int内保存,其原理是在java语言中,int类型使用4 bytes来保存,因此对于需要压缩的int数组,其中的每一个int值的大小不能超过255(2的8次方-1),因此这只是一个实例:
int [] aRGB = {0x56, 0x78, 0x9A, 0xBC}; // 是用16进制保存的4种颜色值
int color_val = aRGB[3];
color_val = color_val | (aRGB[2] <<; // 为了压缩,需要放置到color_val值的第二个字节位置上:将aRGB[2] 左移到第二个byte,同时与color_val进行或操作,下面同理
color_val = color_val | (aRGB[1] << 16);
color_val = color_val | (aRBG[0] << 24);
操作完的结果是56 78 9A BC
如果要从colorVal 还原为int数组,或者得到数组中的某个值,只需要对colorVal 进行相应的右移操作即可:
int alpha_val = (colorVal >>> 24) & 0xFF; int red_val = (colorVal >>> 16) & 0xFF; int green_val = (colorVal >>> 8) & 0xFF; int blue_val = colorVal & 0xFF;
位运算符功能
~ 按位非(NOT)
取反
00101010
11010101
& 按位与(AND)
如果两个操作都是1,则结果为1。在所有其他情况下的结果均为0。
00101010 42
& 00001111 15
-----------------
00001010 10
| 按位或(OR)
如果两个操作数中有一位是1,则结果为1。
00101010 42
| 00001111 15
-----------------
00101111 47
^ 按位异或(xor)
如果两个操作数中有一个是1,则结果就是1,否者是0.
00101010 42
^ 00001111 15
-----------------
00100101 37
>> 向右移位
>>> 向右移位,左边空出的位以0填充
<< 向左移位
&= 按位与并赋值
|= 按位或并赋值
^= 按位异或并赋值
>>= 向右移位并赋值
>>>= 向右移位并赋值,左边空出的位以0填充
<<= 向左移位并赋值
声明为static的方法有几条限制:
它们仅可以调用其他的static方法.
它们只能访问static数据.
它们不能以任何方式引用this和super.
Varagrs:变长参数
两种方法处理变长参数:
1.如果参数否认最大数目不大于已知,则可以为该方法可能被调用的每一种方式创建去重载的版本。
2当参数的最大数目比较大而且不可知的时候,可将这些参数置于一个数组中,然后加数组传递给方法。
public class PassArray { static void vaTest(int v[]) { System.out.print("Number of args: " + v.length + " Contents: "); for(int x : v) System.out.print(x + " "); System.out.println(); } public static void main(String args[]) { // 如何数组 int n1[] = { 10 }; int n2[] = { 1, 2, 3 }; int n3[] = { }; vaTest(n1); // 1 arg vaTest(n2); // 3 args vaTest(n3); // no args } }
static void vaTest(int ... v) 一个变长参数由三个句点(...)来指定。
来代替一个数组,...语法只是告诉编译器将使用可变数目的参数,而这些参数将存储到一个通过v引用的数组中。
如果是多个参数Varagrs参数必须处于最后。例如: int doIt(int a ,int b,double c,int...vals) int doIt(int a ,int b,double c,int...vals,boolean Flag)//error试图申明第二个Varagrs参数是非法的
int doIt(int a ,int b,double c,int... vals,double... vals1)//error
关键词final有三个用途
它可用于创建一个已命名常量的等价物,final的其他两个用法是用于继承的
使用final来阻止重写
listing 19 class A { final void meth() { System.out.println("This is a final method."); } } class B extends A { void meth() { // ERROR! Can't override. System.out.println("Illegal!"); } } 使用final阻止继承 final class A { // ... } // The following class is illegal. class B extends A { // ERROR! Can't subclass A // ... }
导入包
警告 星号形式可能会增加编译时间,特别是在导入几个大包时更是如此,因此一般显示的命名想要使用的类而不是导入整个包,但是星形式对运行时的性能和类的大小却没有什么大的影响。
Threads线程
synchronized ,volatile 两个关键字
当多个线程访问同一个数据项(如静态字段、可全局访问对象的实例字段或共享集合),可以用synchronized ,volatile两个关键字
来实现这个目的。
线程的生命:
创建线程:每个Java程序至少包含一个线程-主线程。其他的线程都是通过Thread构造器或实例化继承类Thread的类来创建的。
创建线程和启动线程并不相同:一个对象拥有一个线程,必须提供一个启动该线程的start()或init()方法,而不是从构造器中启动它。
结束线程:
线程会以以下三种方式之一结束
线程到达其run()方法的末尾。
线程抛出一个未捕获到的Exception或Error。
另一个线程调用一个放弃的stop()方法。弃用是指这些方法仍然存在,但是吧 应该在新代码中使用它们,
并且应该尽量从现有代码中除去它们。
当程序中的搜游程序都完成时,程序就退出了 。
加入线程
join()方法,调用threah.join()
调度
休眠
sleep()方法,当线程进入等待状态,直到过一段指定时间,或者知道另一个线程对当前线程的Thread对象调用了
Thread.interrupt(),中断了线程,线程休眠时会抛出InterruptedException,可以知道线程事中断唤醒的,不必查看计时器是否过期。
Thread.yield()方法就像Thread.sleep()一样,不能引起休眠,而只是暂停当前线程片刻,这样其他的线程就可以运行。
当较高优先级的线程调用Thread.yield()时,较低优先级的线程就不会运行。
守护程序线程
垃圾收集线程和由jvm创建的其他线程等系统线程称作为守护程序线程。
可以通过Thread.setDaemon() 方法来知名摸个线程是守护程序线程
TimerTask线程被标记成守护程序线程
线程间共享数据最简单的形式是:轮询共享变量以查看另一个线程是否已经完成执行某项任务。
存在于同一个内存空间中的所有线程,访问共享变量(静态或实例字段),线程就可以方便的交换数据,但是线程还必须确保他们以受控的方式访问共享变量,以免他们互相干扰对方的更改。
Synchronized有两个重要的含义,他确保了一次只有一个线程可以执行难代码的受保护部分(互斥,mutual exclusion 或者说 mutex),而且它却确保了一个线程更改的数据对于其他线程是可见的(更改的可见性)。
监视器monitor java 锁定合并了一种互斥形式。锁用于保护代码块或整个方法
使用HashMap以线程安全的方式提高高速缓存。
可见性同步的基本规则是在以下情况中必须同步:
读取上一次可能是有另一个线程写入的变量
写入下一次可能有另一个线程读取的变量
1.有静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
2.访问final字段时
3.在创建线程之前创建对象时
4.线程可以看见它将要处理的对象时
以上4点不需要同步
同步准则
使代码块保持简短。不要阻塞。在持有锁的时候,不要对其他对象调用方法。
wait()、notify() 和 notifyAll() 方法
深拷贝(deep clone)与浅拷贝(shallow clone)
浅复制与深复制概念
浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,
而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复
制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆):被复制对象的所有变量都含有与原来的对象相同的值,
除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过
的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制
的对象所引用的对象都复制了一遍。
Java的clone()方法【定义在Object类中】
clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x
克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()
克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
Java中对象的克隆
①为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
②在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
③在派生类的clone()方法中,调用super.clone()。
④在派生类中实现Cloneable接口。不实现Cloneable接口会出现CloneNotSupportedException异常
说明:
①为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?
在运行时刻,Object中的clone()识别出你要复制的是哪一个对象,然后为此对象分配空间,
并进行对象的复制,将原始对象的内容一一复制到新对象的存储空间中。
②继承自java.lang.Object类的clone()方法是浅复制
利用序列化来做深复制
把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫
做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而原
对象仍然存在于JVM里面。
在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实
际上只是对象的一个拷贝)写到一个流里,再从流里读出来,便可以重建对象。这样做的前
提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可
串行化的对象可否设成transient,从而将之排除在复制过程之外。
注意:Cloneable与Serializable都是marker Interface,也就是说他们只是一个标识接口,
没有定义任何方法。
关于实现Serializable接口的类中的serialVersionUID问题
当一个类实现了Serializable接口时,表明该类可被序列化,这个时候Eclipse会要求你为该
类定义一个字段,该字段名字为serialVersionUID,类型为long,提示信息如下:
The serializable class Student4 does not declare a static final serialVersionUID field of type long
你可以随便写一个,在Eclipse中它替你生成一个,有两种生成方式: 一个是默认的1L,比如:
private static final long serialVersionUID = 1L; 一个是根据类名、接口名、成员方法及
属性等来生成一个64位的哈希字段,
比如:private static final long serialVersionUID = 8940196742313994740L;之类的。
当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个提
示功能告诉你去定义之。 在Eclipse中点击类中warning的图标一下【即那个黄色的图标】,
Eclipse就会自动给定两种生成的方式,如上面所述。如果不想定义它,在Eclipse的设置中也
可以把它关掉的,设置如下
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems 将Serializable class without serialVersionUID的
warning改成ignore即可。
如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了
Serializable这个接口的话,如果没有加入serialVersionUID,Eclipse都会给你warning提示,
这个serialVersionUID为了让该类别Serializable向后兼容。
如果你的对象序列化后存到硬盘上面后,可是后来你却更改了类的field(增加或减少或改名),
当你反序列化时,就会出现Exception的,这样就会造成不兼容性的问题。 但当serialVersionUID
相同时,它就会将不一样的field以type的缺省值Deserialize,这个可以避开不兼容性的问题。
volatile的用法
一个volatile(中文意思是“可变的、不稳定的”)
volatile关键字有什么用?
恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;
一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
ArrayList ,linkedList,Vector三点的区别
1.ArrayList 底层实际是采用数组实现的(并且该数组的类型都是继承Object类型的)
2.如果是JDK6的话,采用Arrays.of()方法来生成一个新的数组,如果是JDK5.0的话使用System.arraycopy方法
3.List list=new ArrayList();时,底层会生成一个长度为10的数组来保存存放所需要的对象。
4.对于ArrayList与Vector来说,底层都是采用数组的方法来实现的(该数组是一个Object类型的数组)
5.对于ArrayList,所有的方法都不是同步的,对于Vector,大部分public的方法都是同步的。
6.对于ArrayList,查找速度非常快,增加和删除 操作非常慢,(本质上是由数组的特性来决定的)
7.对于LinkedList,查找速度非常慢,增加和删除 操作非常快,(本质上是由双向循环链表的特点来决定的)
Reflection中包含了两种基本的技术:探索和按名称使用。以下是对两种方法的描述:
探索指采用一个对象或类,并发现其成员、超类、实现的接口,然后尽可能地使用被发现的元素。
按名字使用指以一个元素的符号名开始,并使用已命名的元素。
通常,探索方法以一个对象开始,并通过调用Object.getClass()方法获得对象的类。类对象有很多方法发现类的内容。以下是部分方法:
getMethods():返回一组表示类或接口的所有公共方法的方法对象数组。
getConstructors():返回一组表示类的所有公共构造器的构造器对象数组。
getFields():返回一组表示类或接口所有公共字段的字段对象数组。
getClasses():返回一组表示所有属于类或接口的公共类和接口(例如,内部类)的类对象数组。
getSuperclass():返回表示类或接口的超类的类对象(接口返回为空值)。
getInterfaces():返回一组表示类或接口执行的所有接口的类对象数组。
你可以通过探索,即应用类字面(如MyClass.class)或使用类名(如Class.forName("mypackage.MyClass"))获得类对象。有了类对象,成员对象方法、构造器或字段可以通过使用成员的符号名获得。以下是最重要的一些技术:
getMethod("methodName", Class...):返回表示接受类参数指定参数的类或接口中名为“methodName”的公共方法的方法对象。
getConstructor(Class...):返回表示接受类参数指定参数的类公共构造器的构造器对象。
getField("fieldName"):返回表示类或接口中名为“fieldname”的公共字段的字段对象。
你可以使用Method、Constructor和Field(字段)对象动态地访问类表示成员。例如:
Field.get(Object):返回一个包含输入get()对象实例的字段值对象。(如果字段对象表示静态字段,那么对象参数便被忽略,也可能为空。)
Method.invoke(Object, Object...):返回一个包含为输入invoke()的第一个对象参数实例调用方法的结果的对象。其余对象参数被传递给输入方法。(如果方法对象表示一个静态方法,那么第一个对象参数便被忽略,也可能为空。)
Constructor.newInstance(Object...):返回调用构造器的新对象实例。对象参数输入构造器。(注意类的无参数构造器也可以通过newInstance()被调用。)
创建数组和代理类
java.lang.reflect包提供一个数组,其中包含了可创建和操控数组对象的静态方法。从J2SE 1.3开始,java.lang.reflect包还提供了一个代理类,它支持动态创建用来实现指定接口的代理类。
代理类的执行由执行InvocationHandler接口的一个补充对象完成。代理对象的每个调用方法调用InvocationHandler的方法调用(对象、方法、对象[])——第一参数是代理对象,第二参数是表示代理所执行接口的方法的方法对象,而第三参数是输入接口方法的参数数组。invoke()方法返回一个对象结果,其中包含返回调用代理接口方法的代码的结果。
发表评论
-
maven 不建立仓库直接加入直接的jar
2012-10-26 10:45 1417<dependency> <grou ... -
HTTP协议详解(真的很经典)
2011-02-16 14:16 1135引言 ... -
git中文资料
2011-02-16 10:06 1139Git入门教程 http://hi.baidu.com/eeh ... -
北京圣思园视频下载及时跟新
2011-01-25 11:44 1780北京圣思园张龙(风中叶)老师的Java Web培训的视频,咨询 ... -
二分查找
2010-12-07 13:11 878public class TestBinSearch { ... -
FlashFXP
2010-12-06 09:48 705-------- FlashFXP Registration ... -
Netbeans 6.9.1 设置为英文界面
2010-11-22 09:29 1141问题:从官网下载的netbeans不论是中文版还是英文版默认的 ... -
Fat jar 非常不错的打包插件
2010-08-25 06:30 774http://fjep.sourceforge.net/ -
实践与共享:微软近日发布麾下杀毒软件最新版本 Microsoft Security Essentials 2.0 中文版
2010-08-13 12:22 870近日,微软将其麾下杀毒软件“MSE”升级到了V2.0.3 ... -
推荐Swing编程学习网站
2010-08-12 19:20 887本人向大家提供几个个Swing学习交流的平台 swingch ... -
“第六感装置”的惊人潜力
2010-03-19 23:13 1026我们总是在于“现实生活”和“电脑的数字生活”中的差异,这两个世 ... -
vim笔记
2010-01-04 16:48 836vi的模式mode NormalMode :命令模式,使用a、 ... -
IntelliJ Idea 常用快捷键
2009-10-08 20:41 717Alt+回车 导入包,自动修正 Ctrl+N 查找类 Ct ... -
Eclipse提高工作效率的好习惯
2009-09-09 10:38 896Eclipse 快捷键设置-更 ... -
共享内存在Java中的实现和应用
2009-07-14 17:21 928共享内存在Java中的实现 ... -
jsp笔记
2009-07-14 17:17 629JSP 的9 个内置对象 application: java ... -
命令文档
2009-07-09 20:58 819net use \\ip\ipc$ " " ... -
[转]常用正则表达式收集
2009-06-24 14:35 818正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常 ... -
Url Rewrite Filter 3.1.0
2009-06-23 14:26 3466http://urlrewritefilter.googlec ... -
Excel中如何一次性去掉多个超链接
2009-06-15 17:44 29311.点击“宏”→“查看宏”,选择“宏名”下的“RemoveHy ...
相关推荐
java基础笔记整理java基础笔记整理
Java 基础笔记 Java 是一种广泛使用的高级编程语言,它由 Sun Microsystems 公司开发,现归属 Oracle 公司所有。Java 语言是一种面向对象的编程语言,具有平台独立性、对象封装、继承和多态等特征。下面是 Java ...
这份"JAVA基础笔记"涵盖了从入门到进阶的关键知识点,对于初学者或是希望巩固基础的开发者来说,都是一份宝贵的资源。 笔记可能包括以下几个部分: 1. **Java简介**:Java的起源、特点和应用领域,以及为什么它在...
Java 基础笔记 Java 是一种高级程序设计语言,应用广泛。本笔记将从基本概念开始,详细讲解 Java 的基础知识。 搭建环境和编译运行 在 Java 中,编译和运行程序需要搭建环境。首先,需要编写 Java 源代码,例如:...
JAVA基础笔记整合,java基础部分的一些笔记整合,适合初学者。
“尚硅谷JAVA基础笔记”涵盖了Java语言的基础知识,包括语言概述、基本语法、面向对象概念、封装、继承和多态,以及一些关键概念如形参与实参、属性与局部变量、构造器、this关键字、包和MVC设计模式的使用。...
《黑马程序员Java基础笔记》是一份全面覆盖Java编程基础知识的学习资料,旨在帮助初学者迅速掌握Java编程语言,能够独立编写Java程序。这份笔记由多个部分组成,分别详细讲解了Java的基础语法、集合、多线程、IO以及...
根据提供的信息,我们可以总结出以下Java...以上就是基于提供的“Java基础笔记”内容所整理的关键知识点。这些知识点涵盖了位运算、控制结构、方法定义及对象创建等基本概念,对于Java初学者来说是非常重要的入门知识。
传智博客的JAVA基础笔记个人总结是一份全面的学习资源,旨在帮助初学者或有一定基础的开发者巩固和提升Java编程技能。这份笔记是基于传智播客的课程内容,结合了牛牧老师和水镜老师的讲解精华,提供了27天的学习计划...
这份"Java基础笔记"涵盖了初学者需要掌握的关键知识点,旨在帮助快速入门Java编程。以下是对这些笔记内容的详细解读: 1. **Java简介**:Java是由Sun Microsystems(现已被Oracle公司收购)于1995年发布的面向对象...
《李兴华老师Java基础笔记》是一份全面且详尽的Java学习资料,由知名教育者李兴华老师精心编撰。这份笔记涵盖了Java编程语言的基础到进阶的知识点,旨在帮助初学者和有一定经验的开发者巩固Java技能,提升编程能力。...
java总结,java笔记,java基础学习
这份"Java基础笔记"涵盖了成为一名合格Java程序员所必须掌握的基础知识。 首先,笔记从基本数据类型开始讲解。Java有八种基本数据类型,包括整型(byte、short、int、long)、浮点型(float、double)、字符型...
【小龙的基础笔记】是针对Java初学者的一份详尽教程,由知名导师“龙哥”精心编撰。这份笔记集合了Java编程语言的基础知识,旨在帮助读者从零开始掌握这门广泛使用的编程语言。以下是对笔记中涉及的主要知识点的详细...
黑马Java基础笔记是一份详尽的教程,旨在帮助初学者或自学人员扎实地掌握Java编程的基础。 首先,笔记可能涵盖了Java语言的基础语法,包括数据类型、变量、常量和运算符。Java提供了两种主要的数据类型:基本类型...
java基础知识点笔记,讲述了java的所有基础知识点,没有遗漏。从基础知识到通信,线程等。
【小码哥网易云java基础笔记(Excel完整版)】是网易云课堂知名讲师小码哥精心编撰的一份Java编程基础知识的学习资料。这份笔记涵盖了Java语言的核心概念、语法结构以及实际开发中的常见问题,旨在帮助初学者系统地...