`
C_J
  • 浏览: 124945 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JDK1.6 Study Note about Source Code

阅读更多
xstream
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;
    }





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics