- 浏览: 128906 次
- 性别:
- 来自: 北京
-
最新评论
-
C_J:
有必要这么鸡冻咩?
编写自己的ClassLoader知识点 -
jason61719:
你这不是说了等于没说吗……就解析个loadClass(),谁不 ...
编写自己的ClassLoader知识点 -
jiming:
tedeyang 写道很好的改进,不过话说回来,mybatis ...
开源,从关注产品社区做起(ibatis3.x的最近一个issue展示) -
C_J:
独爱Java 写道好像实际用处并不是很大,只是多了解了有这个东 ...
Java内存模型笔记 -
独爱Java:
好像实际用处并不是很大,只是多了解了有这个东西而已。。。
Java内存模型笔记
xstream
jodo <--->xml
需要解决的问题是根据字符串来转换到类型问题。在 basic里面就有关实现:
以 charConverter.java为例
sax
实现sax 的主要类是:
ParserAdapter.java
以上是其主要的数据结构
涉及到的其他操作有以上数据结构的set() get()方法和 public void startElement() public void endElement()方法
其他几个重要的数据结构类有:AttributesImpl NamespaceSupport AttributeListAdapter
Object的 wait() notify() notifyAll()方法
我觉得昨天那个面试官说的有点偏差
下面是这几个方法的官方注释:
字符串转10进制数字
方法:Integer.parseInt(String s,int radix)//radix制转换的进制,这里是10
{
对s,radix进行合法性判断
对s进行正负判断
这里涉及到的重要方法是
Character.digit((int)s.charAt(i++),radix);//强制转换
{
获取plane int plane = getPlane(codePoint){ return (ch >>> 16);}
根据plane值,做响应运算(这里我没看懂是什么意思)
在 jdk1.5上用的是dom和sax
Dom被收录在W3C标准下。包名称为:org.w3c.dom
包大概分几个部分:
Parsers:(xml剖析器)
这个包下面大概有几个类
接口类:
public abstract class DocumentBuilder
public abstract class DocumentBuilderFactory
class FactoryFinder
异常类:
public class FactoryConfigurationError extends Error
public class ParserConfigurationException extends Exception
class SecuritySupport
public abstract class DocumentBuilderFactory
关键字:建设工厂 抽象类
public void setNamespaceAware(boolean awareness)
public void setValidating(boolean validating)
Publicvoid setIgnoringElementContentWhitespace(boolean whitespace)
public void setExpandEntityReferences(boolean expandEntityRef)
public void setIgnoringComments(boolean ignoreComments)
public void setCoalescing(boolean coalescing)
以上是设置些配置 都是boolean类型变量
public abstract void setAttribute(String name, Object value)
public abstract Object getAttribute(String name)
public abstract void setFeature(String name, boolean value)
public abstract boolean getFeature(String name)
以上是让子类自己实现扩展的一些属性
小结: 基本这个类是获得一个工厂实例和设置工厂的属性。
public abstract class DocumentBuilder
public Document parse(InputStream is)
public Document parse(InputStream is, String systemId)
public Document parse(String uri)
public Document parse(File f) throws SAXException, IOException
public abstract Document parse(InputSource is)
以上就是这个类的重头戏了,以InputStream String File 为参数构造一个Document对象
下面看看具体实现:
InputSource in = new InputSource(is);
return parse(in);
通过发现,原来这些都传给另一个叫InputSource()的类来做处理。那看看InputSource类。
原来InputSource类也只是简单把InputStream String File这些输入存储起来而已,并不做更改。
如:
public void setByteStream (InputStream byteStream)
{
this.byteStream = byteStream;
}
真正的所有构造 留给了 public abstract Document parse(InputSource is)这个方法的子类来做。
public interface Document extends Node
先看看Node接口,看看他有哪些方法。
public String getNodeName();
public String getNodeValue()
public void setNodeValue(String nodeValue)
public Node getFirstChild();
public Node getNextSibling();
public Node insertBefore(Node newChild,
Node refChild)
throws DOMException;
public Node replaceChild(Node newChild,
Node oldChild)
throws DOMException;
public Node removeChild(Node oldChild)
throws DOMException;
基本包含了对XML元素(节点)的所有公共操作了。
“public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
此实现假定哈希函数将元素正确分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代集合视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大小(键-值映射关系数)的和成比例。所以,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。
HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,通过调用 rehash 方法将容量翻倍。
通常,默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地降低 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动的 rehash 操作以增大表的容量来说,使用足够大的初始容量创建它将使得映射关系能更有效地存储。
注意,此实现不是同步的。如果多个线程同时访问此映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。(结构上的修改是指添加或删除一个或多个映射关系的操作;仅改变与实例已经包含的键关联的值不是结构上的修改。)这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的不同步访问,如下所示:
Map m = Collections.synchronizedMap(new HashMap(...));
由所有此类的“集合视图方法”所返回的迭代器都是快速失败 的:在迭代器创建之后,如果从结构上对映射进行修改,除非通过迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒在将来不确定的时间任意发生不确定行为的风险。
注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。 ”
#####################String源码分析,今天偶然间看到了JDK的具体实现,马上就对String.java感兴趣了。然后自己来分析分析下代码吧 ,这里包括从java的到c语言中的alloc的整个过程。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
//看到String类被设计成不可不变类 final class,减弱了性能但提高了安全性
/** The value . */
//最终用于存储字符串的定义域
private final char value[];
//当前下标
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
//下面是构造函数
//看到在new String()对象的时候,字符串长度是0的,但value是含有一个字节的
public String() {
this.offset = 0;
this.count = 0;
this.value = new char[0];
}
//通过String对象构造String对象
public String(String original) {
int size = original.count;//获取字符串的长度,因为count是private变量,所以可以直接引用
char[] originalValue = original.value;//获取指针
char[] v;//用临时变量,进行值传递
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
#####################如果超出字符串长度,则申请新的内存 上面的copyOfRange(char [],int,int)实现如下:
public static char[] copyOfRange(char[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)//如果非法,抛出异常
throw new IllegalArgumentException(from + " > " + to);
char[] copy = new char[newLength];//申请新对象
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));//char[]拷贝
return copy;//返回对象,进行值拷贝
}
######################以上的arraycopy(Object src, int srcPos, Object dest, int destPos, int length)是调用接口实现如下:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
看到熟悉的native语言定义了吧!!
类似的操作包括: public String(char value[]) public String(char value[], int offset, int count)
看看char []到String 的复制
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.offset = 0;
this.count = count;
this.value = Arrays.copyOfRange(value, offset, offset+count);//看到这里就能自己来提取char[]值了,这也是String 到char []的转换实现
}
还有其他类似的构造方法:
public String(int[] codePoints, int offset, int count)
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count)
public String(byte bytes[], int offset, int length, Charset charset)
public String(StringBuffer buffer) {
String result = buffer.toString(); //..........................
this.value = result.value;
this.count = result.count;
this.offset = result.offset;
}
public int length() {
return count;
}
public boolean isEmpty() {
return count == 0;
}
public char charAt(int index) {//返回某个值
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
static int codePointCountImpl(char[] a, int offset, int count) { //offset,是当前指针指向的下标
int endIndex = offset + count;
int n = 0;
for (int i = offset; i < endIndex; ) {
n++;
if (isHighSurrogate(a)) {
if (i < endIndex && isLowSurrogate(a)) {
i++;
}
}
}
return n;
}
void getChars(char dst[], int dstBegin) { //复制指定字段
System.arraycopy(value, offset, dst, dstBegin, count);
}
public byte[] getBytes() {
return StringCoding.encode(value, offset, count); //获取byte时候进行改进了,为更好的兼容性 首先进行编码
}
public boolean equals(Object anObject) { //著名的equals判断,也是很多人聊到的,看看官方版的就很明了
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1 != v2[j++])
return false;
}
return true;
}
}
return false;
}
public char[] toCharArray() {
char result[] = new char[count];
getChars(0, count, result, 0);
return result;//很象返回局部变量错误!!!!!!!!!!!!
}
###########################
//字符串比较
public int compareTo(String anotherString) {
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
if (i == j) {
int k = i;
int lim = n + i;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
} else {
while (n-- != 0) {
char c1 = v1;
char c2 = v2[j++];
if (c1 != c2) {
return c1 - c2;
}
}
}
return len1 - len2;
}
//从某一位置比较字符串
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = offset + toffset;
char pa[] = prefix.value;
int po = prefix.offset;
int pc = prefix.count;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > count - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
//从某一位置截取字符串
public String substring(int beginIndex) {
return substring(beginIndex, count);
}
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);//这个很简洁明了
}
//除去字符串尾的空格
public String trim() {
int len = count;
int st = 0;
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[off + st] <= ' ')) {
st++;//计算字符串空白的起始下标
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
len--;//计算字符串空白的长度
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}
//很多字符串截取和重新构造都是new出一个新的字符串来处理的
//String hashCode的计算方法
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
下面是传说中object.java的实现,
它拥有这所以类的权利,象上帝一样安静的,神圣地俯看着大地
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
######################Throwable.java
public void printStackTrace(PrintStream s) {
synchronized (s) {
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (int i=0; i < trace.length; i++)
s.println("\tat " + trace);
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
}
/**
* Initializes the <i>cause</i> of this throwable to the specified value.
* (The cause is the throwable that caused this throwable to get thrown.)
*
public synchronized Throwable initCause(Throwable cause) {
if (this.cause != this)
throw new IllegalStateException("Can't overwrite cause");
if (cause == this)
throw new IllegalArgumentException("Self-causation not permitted");
this.cause = cause;
return this;
}
jodo <--->xml
需要解决的问题是根据字符串来转换到类型问题。在 basic里面就有关实现:
以 charConverter.java为例
public class CharConverter implements Converter, SingleValueConverter { public boolean canConvert(Class type) { return type.equals(char.class) || type.equals(Character.class); } public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { writer.setValue(toString(source)); } public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { String nullAttribute = reader.getAttribute("null"); if (nullAttribute != null && nullAttribute.equals("true")) { return new Character('\0'); } else { return fromString(reader.getValue()); } } public Object fromString(String str) { if (str.length() == 0) { return new Character('\0'); } else { return new Character(str.charAt(0)); } } public String toString(Object obj) { char ch = ((Character)obj).charValue(); return ch == '\0' ? "" : obj.toString(); } }
sax
实现sax 的主要类是:
ParserAdapter.java
private NamespaceSupport nsSupport; private AttributeListAdapter attAdapter; private boolean parsing = false; private String nameParts[] = new String[3]; private Parser parser = null; private AttributesImpl atts = null; // Features private boolean namespaces = true; private boolean prefixes = false; private boolean uris = false; // Properties // Handlers Locator locator; EntityResolver entityResolver = null; DTDHandler dtdHandler = null; ContentHandler contentHandler = null; ErrorHandler errorHandler = null;
以上是其主要的数据结构
涉及到的其他操作有以上数据结构的set() get()方法和 public void startElement() public void endElement()方法
其他几个重要的数据结构类有:AttributesImpl NamespaceSupport AttributeListAdapter
/** * Waits for this thread to die. * * @exception InterruptedException if another thread has interrupted * the current thread. The <i>interrupted status</i> of the * current thread is cleared when this exception is thrown. */ public final void join() throws InterruptedException { join(0); }
Object的 wait() notify() notifyAll()方法
我觉得昨天那个面试官说的有点偏差
下面是这几个方法的官方注释:
/** * Causes current thread to wait until another thread invokes the * {@link java.lang.Object#notify()} method or the * {@link java.lang.Object#notifyAll()} method for this object. * The current thread must own this object's monitor. The thread * releases ownership of this monitor and waits until another thread * notifies threads waiting on this object's monitor to wake up * either through a call to the <code>notify</code> method or the * <code>notifyAll</code> method. The thread then waits until it can * re-obtain ownership of the monitor and resumes execution. **/ public final void wait() throws InterruptedException { wait(0); } /** * Wakes up a single thread that is waiting on this object's * monitor. If any threads are waiting on this object, one of them * is chosen to be awakened. The choice is arbitrary and occurs at * the discretion of the implementation. A thread waits on an object's * monitor by calling one of the <code>wait</code> methods. * <p> * The awakened thread will not be able to proceed until the current * thread relinquishes the lock on this object. The awakened thread will * compete in the usual manner with any other threads that might be * actively competing to synchronize on this object; for example, the * awakened thread enjoys no reliable privilege or disadvantage in being * the next thread to lock this object. * <p> * This method should only be called by a thread that is the owner * of this object's monitor. A thread becomes the owner of the * object's monitor in one of three ways: * <ul> * <li>By executing a synchronized instance method of that object. * <li>By executing the body of a <code>synchronized</code> statement * that synchronizes on the object. * <li>For objects of type <code>Class,</code> by executing a * synchronized static method of that class. * </ul> * <p> * Only one thread at a time can own an object's monitor. * * @exception IllegalMonitorStateException if the current thread is not * the owner of this object's monitor. * @see java.lang.Object#notifyAll() * @see java.lang.Object#wait() */ public final native void notify();
字符串转10进制数字
方法:Integer.parseInt(String s,int radix)//radix制转换的进制,这里是10
{
对s,radix进行合法性判断
对s进行正负判断
while (i < max) { digit = Character.digit(s.charAt(i++),radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); } result -= digit; }
这里涉及到的重要方法是
Character.digit((int)s.charAt(i++),radix);//强制转换
{
获取plane int plane = getPlane(codePoint){ return (ch >>> 16);}
根据plane值,做响应运算(这里我没看懂是什么意思)
int val = getProperties(ch); int kind = val & 0x1F; if (kind == Character.DECIMAL_DIGIT_NUMBER) { value = ch + ((val & 0x3E0) >> 5) & 0x1F; } else if ((val & 0xC00) == 0x00000C00) { // Java supradecimal digit value = (ch + ((val & 0x3E0) >> 5) & 0x1F) + 10; } } return (value < radix) ? value : -1;}
在 jdk1.5上用的是dom和sax
Dom被收录在W3C标准下。包名称为:org.w3c.dom
包大概分几个部分:
Parsers:(xml剖析器)
这个包下面大概有几个类
接口类:
public abstract class DocumentBuilder
public abstract class DocumentBuilderFactory
class FactoryFinder
异常类:
public class FactoryConfigurationError extends Error
public class ParserConfigurationException extends Exception
class SecuritySupport
public abstract class DocumentBuilderFactory
关键字:建设工厂 抽象类
public void setNamespaceAware(boolean awareness)
public void setValidating(boolean validating)
Publicvoid setIgnoringElementContentWhitespace(boolean whitespace)
public void setExpandEntityReferences(boolean expandEntityRef)
public void setIgnoringComments(boolean ignoreComments)
public void setCoalescing(boolean coalescing)
以上是设置些配置 都是boolean类型变量
public abstract void setAttribute(String name, Object value)
public abstract Object getAttribute(String name)
public abstract void setFeature(String name, boolean value)
public abstract boolean getFeature(String name)
以上是让子类自己实现扩展的一些属性
小结: 基本这个类是获得一个工厂实例和设置工厂的属性。
public abstract class DocumentBuilder
public Document parse(InputStream is)
public Document parse(InputStream is, String systemId)
public Document parse(String uri)
public Document parse(File f) throws SAXException, IOException
public abstract Document parse(InputSource is)
以上就是这个类的重头戏了,以InputStream String File 为参数构造一个Document对象
下面看看具体实现:
InputSource in = new InputSource(is);
return parse(in);
通过发现,原来这些都传给另一个叫InputSource()的类来做处理。那看看InputSource类。
原来InputSource类也只是简单把InputStream String File这些输入存储起来而已,并不做更改。
如:
public void setByteStream (InputStream byteStream)
{
this.byteStream = byteStream;
}
真正的所有构造 留给了 public abstract Document parse(InputSource is)这个方法的子类来做。
public interface Document extends Node
先看看Node接口,看看他有哪些方法。
public String getNodeName();
public String getNodeValue()
public void setNodeValue(String nodeValue)
public Node getFirstChild();
public Node getNextSibling();
public Node insertBefore(Node newChild,
Node refChild)
throws DOMException;
public Node replaceChild(Node newChild,
Node oldChild)
throws DOMException;
public Node removeChild(Node oldChild)
throws DOMException;
基本包含了对XML元素(节点)的所有公共操作了。
“public class HashMap<K,V>extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
此实现假定哈希函数将元素正确分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代集合视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大小(键-值映射关系数)的和成比例。所以,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。
HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,通过调用 rehash 方法将容量翻倍。
通常,默认加载因子 (.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地降低 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动的 rehash 操作以增大表的容量来说,使用足够大的初始容量创建它将使得映射关系能更有效地存储。
注意,此实现不是同步的。如果多个线程同时访问此映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。(结构上的修改是指添加或删除一个或多个映射关系的操作;仅改变与实例已经包含的键关联的值不是结构上的修改。)这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的不同步访问,如下所示:
Map m = Collections.synchronizedMap(new HashMap(...));
由所有此类的“集合视图方法”所返回的迭代器都是快速失败 的:在迭代器创建之后,如果从结构上对映射进行修改,除非通过迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒在将来不确定的时间任意发生不确定行为的风险。
注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。 ”
#####################String源码分析,今天偶然间看到了JDK的具体实现,马上就对String.java感兴趣了。然后自己来分析分析下代码吧 ,这里包括从java的到c语言中的alloc的整个过程。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
//看到String类被设计成不可不变类 final class,减弱了性能但提高了安全性
/** The value . */
//最终用于存储字符串的定义域
private final char value[];
//当前下标
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
//下面是构造函数
//看到在new String()对象的时候,字符串长度是0的,但value是含有一个字节的
public String() {
this.offset = 0;
this.count = 0;
this.value = new char[0];
}
//通过String对象构造String对象
public String(String original) {
int size = original.count;//获取字符串的长度,因为count是private变量,所以可以直接引用
char[] originalValue = original.value;//获取指针
char[] v;//用临时变量,进行值传递
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
#####################如果超出字符串长度,则申请新的内存 上面的copyOfRange(char [],int,int)实现如下:
public static char[] copyOfRange(char[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)//如果非法,抛出异常
throw new IllegalArgumentException(from + " > " + to);
char[] copy = new char[newLength];//申请新对象
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));//char[]拷贝
return copy;//返回对象,进行值拷贝
}
######################以上的arraycopy(Object src, int srcPos, Object dest, int destPos, int length)是调用接口实现如下:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
看到熟悉的native语言定义了吧!!
类似的操作包括: public String(char value[]) public String(char value[], int offset, int count)
看看char []到String 的复制
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.offset = 0;
this.count = count;
this.value = Arrays.copyOfRange(value, offset, offset+count);//看到这里就能自己来提取char[]值了,这也是String 到char []的转换实现
}
还有其他类似的构造方法:
public String(int[] codePoints, int offset, int count)
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count)
public String(byte bytes[], int offset, int length, Charset charset)
public String(StringBuffer buffer) {
String result = buffer.toString(); //..........................
this.value = result.value;
this.count = result.count;
this.offset = result.offset;
}
public int length() {
return count;
}
public boolean isEmpty() {
return count == 0;
}
public char charAt(int index) {//返回某个值
if ((index < 0) || (index >= count)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index + offset];
}
static int codePointCountImpl(char[] a, int offset, int count) { //offset,是当前指针指向的下标
int endIndex = offset + count;
int n = 0;
for (int i = offset; i < endIndex; ) {
n++;
if (isHighSurrogate(a)) {
if (i < endIndex && isLowSurrogate(a)) {
i++;
}
}
}
return n;
}
void getChars(char dst[], int dstBegin) { //复制指定字段
System.arraycopy(value, offset, dst, dstBegin, count);
}
public byte[] getBytes() {
return StringCoding.encode(value, offset, count); //获取byte时候进行改进了,为更好的兼容性 首先进行编码
}
public boolean equals(Object anObject) { //著名的equals判断,也是很多人聊到的,看看官方版的就很明了
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1 != v2[j++])
return false;
}
return true;
}
}
return false;
}
public char[] toCharArray() {
char result[] = new char[count];
getChars(0, count, result, 0);
return result;//很象返回局部变量错误!!!!!!!!!!!!
}
###########################
//字符串比较
public int compareTo(String anotherString) {
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
if (i == j) {
int k = i;
int lim = n + i;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
} else {
while (n-- != 0) {
char c1 = v1;
char c2 = v2[j++];
if (c1 != c2) {
return c1 - c2;
}
}
}
return len1 - len2;
}
//从某一位置比较字符串
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = offset + toffset;
char pa[] = prefix.value;
int po = prefix.offset;
int pc = prefix.count;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > count - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
//从某一位置截取字符串
public String substring(int beginIndex) {
return substring(beginIndex, count);
}
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);//这个很简洁明了
}
//除去字符串尾的空格
public String trim() {
int len = count;
int st = 0;
int off = offset; /* avoid getfield opcode */
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[off + st] <= ' ')) {
st++;//计算字符串空白的起始下标
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
len--;//计算字符串空白的长度
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}
//很多字符串截取和重新构造都是new出一个新的字符串来处理的
//String hashCode的计算方法
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
下面是传说中object.java的实现,
它拥有这所以类的权利,象上帝一样安静的,神圣地俯看着大地
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
######################Throwable.java
public void printStackTrace(PrintStream s) {
synchronized (s) {
s.println(this);
StackTraceElement[] trace = getOurStackTrace();
for (int i=0; i < trace.length; i++)
s.println("\tat " + trace);
Throwable ourCause = getCause();
if (ourCause != null)
ourCause.printStackTraceAsCause(s, trace);
}
}
/**
* Initializes the <i>cause</i> of this throwable to the specified value.
* (The cause is the throwable that caused this throwable to get thrown.)
*
public synchronized Throwable initCause(Throwable cause) {
if (this.cause != this)
throw new IllegalStateException("Can't overwrite cause");
if (cause == this)
throw new IllegalArgumentException("Self-causation not permitted");
this.cause = cause;
return this;
}
发表评论
-
iOS入门(ongoing)
2012-09-13 11:32 1315Record it: The overview of ... -
Stuff about Android
2011-07-09 16:15 1083Foreword: long time ... -
JQuery初体验(Demo)
2011-05-22 13:43 1471Demo:Show <meta content ... -
Java内存模型笔记
2011-04-13 15:48 1551题记: 看到C/C++ ... -
Radiant_The Popular Ruby's CMS Demo篇
2011-04-02 14:49 1259题记: 上篇 记录我第一次安装Rodiant经过和 ... -
Radiant_The Popular Ruby’s CMS安装篇
2011-03-28 00:48 1331题记: 今天第一次参加JE的线下活动,robbin等 ... -
关于Azul 并发垃圾回收器
2011-03-26 14:40 1332题记: 总感觉JE讨论的帖子的东西都比较滞后,所以会 ... -
phpCMS & jQuery是我该做的(阉割了)
2011-02-27 23:02 81WD讲究以plugin挂载为结构,我需要构造一个p ... -
我的玩意:J2ME的Criteria初探
2011-01-20 21:59 1032题记: 前几天跟初中同学聊天,他问我能不能做一个GP ... -
编写自己的ClassLoader知识点
2011-01-13 14:41 1880题记: 看到InfoQ关于ClassLoader的文 ... -
周末好玩,用短信控制你的计算机
2011-01-10 16:34 3015Snapshot: 详情 ... -
About Dock Plugin on Mac
2010-11-21 22:47 1476题记: 第一次接触MAC的开发..... ... -
可变hashcode的隐患和序列化安全
2010-10-25 00:55 1385可变hashcode的隐患 为识别对象,JDK ... -
体验OSGi(helloworld.jar)—富app的热拔插
2010-10-18 23:22 2457记得以前工作的时候,有天direct manager问 ... -
MongoDB on DAO with Java Language
2010-08-26 19:17 1442A Quick Tour Using the Java d ... -
Getting Start on Mongodb
2010-08-26 01:29 1528题记: 最近老和同学聊到non-relational ... -
Java Media Framework本地玩转摄像头
2010-08-04 00:57 17571、简介The JavaTM Media Framework ... -
从WeakLogHandler应用看Java的引用、引用队列
2010-06-14 00:58 1513题记: 前几天讨论到WeakHashMap(这个是个弱引用的 ... -
《重构》读书笔记
2010-05-09 00:05 1063Martin Fowler于2003年出版 ... -
RPC之WebServices&RMI&JMS,phprpc框架?(待续)
2010-05-06 22:31 55前段时间写过基本的WebServices,也没再做深入 ...
相关推荐
mac for jdk1.6 jdk6 安装版 里面有两个jdk1.6的安装包,都可以用 如果电脑上安装有1.7,1.8等高版本jdk就不要再下安装包了,安装包安装会报错 命令是这个:brew install java6或 brew install homebrew/cask-...
标题中的“jdk1.6集成jjwt的问题”指的是在Java Development Kit (JDK) 版本1.6的环境下,尝试整合JSON Web Token (JWT) 库jjwt时遇到的挑战。JWT是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为 ...
1.okhttp3.8源码使用jdk1.6重新编译,已集成了okio,在javaweb项目中使用,未在安卓项目中使用 2.okhttp3.8源码使用jdk1.6重新编译_okhttp3.8.0-jdk1.6.jar
aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-15.8.0-jdk1.6aspose-words-...
**JDK 1.6版本详解** Java Development Kit(JDK)是Oracle公司提供的用于开发和运行Java应用程序的工具集合。JDK 1.6,也被称为Java SE 6,是Java平台的一个重要版本,发布于2006年12月11日。这个版本在Java社区中...
- **下载**:从Oracle官网或其他可信源下载JDK 1.6的安装文件,如"jdk1.6.exe"。 - **安装**:双击执行安装文件,按照向导步骤进行安装,选择合适的安装路径。 - **环境变量设置**:安装完成后,需要在系统环境变量...
根据提供的标题、描述以及部分内容,我们可以总结出与JDK1.6百度云下载相关的几个重要知识点: ### 一、JDK1.6简介 Java Development Kit(简称JDK)是Sun Microsystems公司针对Java语言开发的一套开发工具包,它...
JDK1.6是Oracle公司发布的一个早期版本,虽然现在已有更新的版本如JDK 8、11或17,但有些老旧的项目可能仍依赖于这个版本。本文将深入探讨JDK1.6的特点、用途以及免安装版的优缺点。 首先,JDK1.6包含了Java编译器...
JDK1.6是Oracle公司发布的一个较早版本,适用于Windows操作系统。在这个解压版中,用户无需进行安装过程,可以直接在Windows环境下使用JDK的各个工具。 JDK1.6包含的主要组件有: 1. **Java编译器**(javac):...
本资源是JDK 1.6的32位免安装纯绿色版本,非常适合那些希望快速启动Java开发而无需进行复杂安装过程的用户。 JDK 1.6,也被称为Java SE 6,是Sun Microsystems(后被Oracle公司收购)发布的Java平台标准版的一个...
《OkHttp3.8.0-JDK1.6:低版本环境下的高效网络通信库》 OkHttp3.8.0-jdk1.6.zip是一个专门为Java Web项目设计的网络通信库,它针对JDK1.6进行了优化和重新编译,确保在较低版本的Java环境中也能稳定运行。OkHttp,...
JDK 1.6 绿色版,我想很多人可能都需要,这是分卷4,剩下的分卷地址如下: JDK 1.6 绿色版 2 http://download.csdn.net/source/1502201 JDK 1.6 绿色版 3 http://download.csdn.net/source/1502209 JDK 1.6 绿色版...
**Java Development Kit (JDK) 1.6详解** Java Development Kit (JDK) 是Java编程语言的核心组件,用于开发和运行Java应用程序。JDK 1.6是Oracle公司发布的一个重要版本,它包含了编译器、Java虚拟机(JVM)、类库...
JDK1.6是Oracle公司发布的一个早期版本,发布于2009年,它是Java SE(标准版)平台的一个重要版本。这个“免安装版”意味着它不需要通过传统安装程序在Windows x64系统上设置,而是可以直接解压并使用,方便用户快速...
JDK 1.6,也称为Java SE(标准版)6,是Java编程语言的一个早期版本,发布于2006年。它包含了Java编译器、Java虚拟机(JVM)、Java类库以及开发者用来创建、调试和部署Java应用程序所需的各种工具。 **JDK 1.6的...
在给定的"jdk1.6解压版(免安装版)"中,用户无需经历传统意义上的安装过程,只需将压缩包解压到指定位置,然后配置系统环境变量,就可以开始使用这个版本的JDK进行Java程序的开发和运行。 1. **JDK1.6**:这是Java的...
Java Development Kit (JDK) 1.6 是一个重要的Java平台版本,它引入了许多新特性以增强开发者的体验,其中包括对Web服务(Web Services)的全面支持。Web服务是一种通过互联网进行应用程序之间的通信方式,允许不同...
这个jar包特别针对JDK1.6进行了优化和适配,确保在该版本的Java环境中能够正常运行。ZXing库广泛应用于移动设备和服务器端,允许程序生成和读取多种类型的条形码和二维码,如QR Code、Aztec、Code 39、EAN-13等。 1...
在资源文件中的`解决JDK1.6下的Base64.jar`可能是包含了一个兼容JDK 1.6的Base64实现的第三方库,你可以直接将这个jar包添加到你的项目类路径中,这样就可以使用其中提供的Base64类而无需修改代码。添加方法通常包括...
IBM JDK 1.6是IBM公司为Java开发者提供的一个针对Linux 64位操作系统的Java开发工具包。这个版本的JDK是Java平台标准版(Java SE)的一部分,主要用于开发和运行Java应用程序、Web应用程序以及企业级应用。IBM JDK与...