1. 程式人生 > >JAVA 與 MyCat(4) XML解析詳解

JAVA 與 MyCat(4) XML解析詳解

通過mycat來學習java了^^。

前一篇講到了load方法:

private void load(String dtdFile, String xmlFile) {
		InputStream dtd = null;
		InputStream xml = null;
		try {
			dtd = XMLSchemaLoader.class.getResourceAsStream(dtdFile);
			xml = XMLSchemaLoader.class.getResourceAsStream(xmlFile);
			Element root = ConfigUtil.getDocument(dtd, xml).getDocumentElement();
			// 先載入所有的DataHost
			loadDataHosts(root);
			// 再載入所有的DataNode
			loadDataNodes(root);
			// 最後載入所有的Schema
			loadSchemas(root);
		} catch (ConfigException e) {
			throw e;
		} catch (Exception e) {
			throw new ConfigException(e);
		} finally {


			if (dtd != null) {
				try {
					dtd.close();
				} catch (IOException e) {
				}
			}


			if (xml != null) {
				try {
					xml.close();
				} catch (IOException e) {
				}
			}
		}
}

第一個知識點:getResourceAsStream(fileName)的檔案位置,已經講了,接著往下看:
Element root = ConfigUtil.getDocument(dtd, xml).getDocumentElement();

看看ConfigUtil.getDocument(dtd, xml)方法的內容,此時方法的引數值為/rule.dtd和/rule.xml:

public static Document getDocument(final InputStream dtd, InputStream xml) throws ParserConfigurationException,
            SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(false);
        DocumentBuilder builder = factory.newDocumentBuilder();
        builder.setEntityResolver(new EntityResolver() {
            @Override
            public InputSource resolveEntity(String publicId, String systemId) {
                return new InputSource(dtd);
            }
        });
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException e) {
            }

            @Override
            public void error(SAXParseException e) throws SAXException {
                throw e;
            }

            @Override
            public void fatalError(SAXParseException e) throws SAXException {
                throw e;
            }
        });
        return builder.parse(xml);
}
該方法就是通過對rule.xml的解析,返回一個w3c的Document型別,用來存放xml檔案內容。這又是一個知識點:


XML文件解析:四種方式的簡單總結

對XML的解析網上有許多文章,有興趣可以搜一下,一大把,這裡不做過多重複,只對重點列舉一下:

以如下XML文件進行展示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
	<tableRule name="mod-long">
		<rule>
			<columns>user_id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="mod-long-from">
		<rule>
			<columns>from_user_id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>
	<tableRule name="mod-long-to">
		<rule>
			<columns>to_user_id</columns>
			<algorithm>mod-long</algorithm>
		</rule>
	</tableRule>

	<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<property name="count">2</property>
		<property name="defaultNode">0</property>
	</function>

</mycat:rule>



1.DOM解析,適合XML檔案小的場景

最原始的解析方式,將整個XML文件讀入記憶體,按層次解析成一棵樹,容易理解,可以隨機訪問樹的任意部分,但如果XML文件比較大,會佔用大量記憶體。這種解析方式適用於XML檔案比較小的場景。

package io.mycat.test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;


public class DOMrw {

	public static void main(String[] args) {
		parse();
	}

	public static void parse() {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder builder = dbf.newDocumentBuilder();
			InputStream in = DOMrw.class.getResourceAsStream("/rule.xml");
			Document doc = builder.parse(in);
			// root <mycat:rule>
			Element root = doc.getDocumentElement();
			System.out.print(root.getNodeName());
			NamedNodeMap nnm = root.getAttributes();
			for (int i = 0; i < nnm.getLength(); i++) {
				Node n = nnm.item(i);
				System.out.print(" " + n.getNodeName() + "=" + n.getNodeValue() + " ");
			}
			System.out.println();
			// all tableRule, function node
			NodeList nodes = root.getChildNodes();

			print(nodes, 1);

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	private static void print(NodeList nodes, int ind) {
		NamedNodeMap nnm;
		String txt;
		for (int i = 0; i < nodes.getLength(); i++) {
			Node node = nodes.item(i);
			if (node.getNodeType() == Node.TEXT_NODE) {
				txt = node.getTextContent();
				if (txt.replaceAll("\n", "").replaceAll("\t", "").replaceAll(" ", "").length() > 0) {
					for (int j = 0; j < ind; j++) {
						System.out.print("  ");
					}
					System.out.print("[" + node.getTextContent() + "]");
					System.out.println();
				}
			}
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				for (int j = 0; j < ind; j++) {
					System.out.print("  ");
				}
				System.out.print(node.getNodeName());
				nnm = node.getAttributes();
				for (int j = 0; j < nnm.getLength(); j++) {
					Node n = nnm.item(j);
					System.out.print(" " + n.getNodeName() + "=" + n.getNodeValue() + " ");
				}
				System.out.println();
				NodeList nds = node.getChildNodes();
				if (nds.getLength() == 0) {
					System.out.print(node.getTextContent());
				} else {
					print(nds, ind + 1);
				}
			}
		}
	}

}
執行結果:
mycat:rule xmlns:mycat=http://io.mycat/ 
  tableRule name=mod-long 
    rule
      columns
        [user_id]
      algorithm
        [mod-long]
  tableRule name=mod-long-from 
    rule
      columns
        [from_user_id]
      algorithm
        [mod-long]
  function class=io.mycat.route.function.PartitionByMod  name=mod-long 
    property name=count 
      [2]
    property name=defaultNode 
      [0]

上面的java程式碼是xml的解析,也就是讀,把xml檔案裡的內容全部打印出來。上面程式碼裡,沒有寫。

2.SAX解析,記憶體佔用少,響應快,適合XML大文件

SAX與DOM正好相反,佔用記憶體少,但只能順序訪問,不能隨機訪問。SAX在解析XML文件時,按順序會遇到各種文件元素,遇到時就觸發相應的事件,例如startDocument()文件開始事件,endDocument()文件結束事件,startElement()元素開始事件等等,我們重寫這些事件方法,就可以完成我們解析的目的,所以SAX也稱為事件驅動解析。

SAX不會將整個XML文件都事先讀入記憶體,讀過的部分也不保證快取在記憶體裡,所以適合XML大文件的讀取,但只能順序讀取。由於是邊讀邊觸發事件邊處理,所以SAX的響應速度很快。

XML文件裡的元素種類很多,所以對應的事件也很多,但最常用的是startDocument()、endDocument()、startElement()、endElement()、characters()幾個。

package io.mycat.test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXr {
	public static void main(String[] args) {
		parse();
		// write();
	}

	public static void parse() {
		SAXParserFactory saxf = SAXParserFactory.newInstance();

		try {
			SAXParser saxparser = saxf.newSAXParser();
			InputStream in = DOMrw.class.getResourceAsStream("/rule.xml");
			saxparser.parse(in, new MySAXHandler());
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class MySAXHandler extends DefaultHandler {
	boolean hasAttribute = false;
	Attributes attributes = null;

	public void startDocument() throws SAXException {
		System.out.println("文件開始");
	}

	public void endDocument() throws SAXException {
		System.out.println("文件結束");
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if (!uri.isEmpty()) {
			System.out.print("uri=" + uri + " ");
		}
		if (!localName.isEmpty()) {
			System.out.print("localName=" + localName + " ");
		}
		if (!qName.isEmpty()) {
			System.out.print("qName=" + qName + " ");
		}

		for (int i = 0; i < attributes.getLength(); i++) {
			System.out.print(attributes.getQName(i) + ":" + attributes.getValue(i) + " ");
		}
		// System.out.println();
	}

	public void endElement(String uri, String localName, String qName) throws SAXException {

	}

	// characters該當就相當於DOM裡的TEXT_NODE一樣,處理文字資訊
	public void characters(char[] ch, int start, int length) throws SAXException {
		System.out.print(new String(ch, start, length));
	}
}
執行結果:
文件開始
qName=mycat:rule xmlns:mycat:http://io.mycat/ 
	qName=tableRule name:mod-long 
		qName=rule 
			qName=columns user_id
			qName=algorithm mod-long
		
	
	qName=tableRule name:mod-long-from 
		qName=rule 
			qName=columns from_user_id
			qName=algorithm mod-long
		
	
	qName=tableRule name:mod-long-to 
		qName=rule 
			qName=columns to_user_id
			qName=algorithm mod-long
		
	

	qName=function name:mod-long class:io.mycat.route.function.PartitionByMod 
		
		qName=property name:count 2
		qName=property name:defaultNode 0
	

文件結束

SAX在解析時,需要指定handler類,該類繼承DefaultHandler,實現各種事件的處理。

3.JDOM解析,使用簡單

前面的DOM方式和SAX方式解析XML程式碼編寫比較複雜,為了簡化程式碼可以使用JDOM,而且完成相同的功能JDOM的程式碼更高效,但是JDOM不能解決所有的問題。JDOM的目的就是為了解決80%最常見的問題,使這些問題的解決得到極大簡化,而另外20%不常見問題,則需要自己編碼解決,這些問題很少遇到,可以忽略。所以JDOM還是很值得考慮使用的。
JDOM沒有自己的解析器,所以使用的是SAX解析器,但在使用上更類似於DOM,更容易理解。

package io.mycat.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class JDOMr {
	public static void main(String[] args) {
		parse();
		// write();
	}

	public static void parse() {
		SAXBuilder saxBuilder = new SAXBuilder();

		try {
			InputStream in = JDOMr.class.getResourceAsStream("/rule.xml");
			Document document = saxBuilder.build(in); // 這裡的Document是jdom2的Document
			Element root = document.getRootElement(); // 這裡的Element是jdom2的Element
			System.out.print("name=" + root.getName() + " ");
			System.out.print("NamespacePrefix=" + root.getNamespacePrefix() + " ");
			System.out.print("NamespaceURI=" + root.getNamespaceURI() + " ");
			List<Attribute> lattr = root.getAttributes();
			for (Attribute attr : lattr) {
				System.out.print(" " + attr.getName() + "=" + attr.getValue() + " ");
			}
			System.out.println();
			// all tableRule, function node
			List<Element> children = root.getChildren();

			print(children, 1);

		} catch (JDOMException | IOException e) {

			e.printStackTrace();
		}
	}

	private static void print(List<Element> children, int ind) {
		for (Element elt : children) {
			for (int j = 0; j < ind; j++) {
				System.out.print("  ");
			}
			System.out.print(elt.getName());
			List<Attribute> lattr = elt.getAttributes();
			for (Attribute attr : lattr) {
				System.out.print(" " + attr.getName() + "=" + attr.getValue() + " ");
			}
			String txt = elt.getTextTrim();
			if (txt.length() > 0) {
				System.out.print("[" + txt + "]");
			}
			System.out.println();
			// all tableRule, function node
			List<Element> ch = elt.getChildren();

			print(ch, ind + 1);
		}
	}
}
執行結果:
name=rule NamespacePrefix=mycat NamespaceURI=http://io.mycat/ 
  tableRule name=mod-long 
    rule
      columns[user_id]
      algorithm[mod-long]
  tableRule name=mod-long-from 
    rule
      columns[from_user_id]
      algorithm[mod-long]
  tableRule name=mod-long-to 
    rule
      columns[to_user_id]
      algorithm[mod-long]
  function name=mod-long  class=io.mycat.route.function.PartitionByMod 
    property name=count [2]
    property name=defaultNode [0]

通過上面程式碼,可以很明顯地看到,輸出同樣的結束,JDOM的程式碼要少的多。


4.DOM4J解析、最好的解析方式

DOM4J是JDOM的改進,一開始DOM4J只是JDOM的一個智慧分支,後來發展成一款獨立的開源軟體,DOM4J不但可以解決所有的XML解析問題,還包括整合的 XPath 支援、XML Schema 支援以及用於大文件或流化文件的基於事件的處理。總之,DOM4J效能優異、功能強大、極端易用使用。

越來越多的軟體在使用DOM4J,連 Sun 的 JAXM 也在用 DOM4J。所以使用DOM4J處理XML是不錯的選擇。

package io.mycat.test.xml;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class DOM4Jr {
	public static void main(String[] args) {
		parse();
		// write();
	}

	public static void parse() {
		SAXReader reader = new SAXReader();
		try {
			InputStream in = JDOMr.class.getResourceAsStream("/rule.xml");
			Document document = reader.read(in); // 這裡的Document是dom4j的Document
			Element root = document.getRootElement(); // 這裡的Element是dom4j的Element
			System.out.print("name=" + root.getName() + " ");
			System.out.print("NamespacePrefix=" + root.getNamespacePrefix() + " ");
			System.out.print("NamespaceURI=" + root.getNamespaceURI() + " ");
			List<Attribute> lattr = root.attributes();
			for (Attribute attr : lattr) {
				System.out.print(" " + attr.getName() + "=" + attr.getValue() + " ");
			}
			System.out.println();
			// all tableRule, function node
			List<Element> children = root.elements();

			print(children, 1);

		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}

	private static void print(List<Element> children, int ind) {
		for (Element elt : children) {
			for (int j = 0; j < ind; j++) {
				System.out.print("  ");
			}
			System.out.print(elt.getName());
			List<Attribute> lattr = elt.attributes();
			for (Attribute attr : lattr) {
				System.out.print(" " + attr.getName() + "=" + attr.getValue() + " ");
			}
			String txt = elt.getTextTrim();
			if (txt.length() > 0) {
				System.out.print("[" + txt + "]");
			}
			System.out.println();
			// all tableRule, function node
			List<Element> ch = elt.elements();

			print(ch, ind + 1);
		}
	}
}
執行結果:
name=rule NamespacePrefix=mycat NamespaceURI=http://io.mycat/ 
  tableRule name=mod-long 
    rule
      columns[user_id]
      algorithm[mod-long]
  tableRule name=mod-long-from 
    rule
      columns[from_user_id]
      algorithm[mod-long]
  tableRule name=mod-long-to 
    rule
      columns[to_user_id]
      algorithm[mod-long]
  function name=mod-long  class=io.mycat.route.function.PartitionByMod 
    property name=count [2]
    property name=defaultNode [0]

從上面程式碼可以看出,DOM4J與JDOM的程式碼非常類似,程式碼依然簡練,但DOM4J提供的方法更多,完成的功能更多,效率也更高。


上面就是JAVA的XML的四種解析方式,總的來說,優先使用DOM4J的方式。

現在回過頭來再看一下MyCat的XML解析:

   public static Document getDocument(final InputStream dtd, InputStream xml) throws ParserConfigurationException,
            SAXException, IOException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(false);
        DocumentBuilder builder = factory.newDocumentBuilder();
        builder.setEntityResolver(new EntityResolver() {
            @Override
            public InputSource resolveEntity(String publicId, String systemId) {
                return new InputSource(dtd);
            }
        });
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException e) {
            }

            @Override
            public void error(SAXParseException e) throws SAXException {
                throw e;
            }

            @Override
            public void fatalError(SAXParseException e) throws SAXException {
                throw e;
            }
        });
        return builder.parse(xml);
    }
首先:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(false);
        DocumentBuilder builder = factory.newDocumentBuilder();
這一段用的是javax.xml.parsers包裡的JAVA自帶的基本類。接下來:
builder.setEntityResolver(new EntityResolver() {
            @Override
            public InputSource resolveEntity(String publicId, String systemId) {
                return new InputSource(dtd);
            }
        });
        builder.setErrorHandler(new ErrorHandler() {
            @Override
            public void warning(SAXParseException e) {
            }

            @Override
            public void error(SAXParseException e) throws SAXException {
                throw e;
            }

            @Override
            public void fatalError(SAXParseException e) throws SAXException {
                throw e;
            }
        });
這一段用的又是SAX的XML解析,最後:
return builder.parse(xml);
返回的又是org.w3c.dom包的Document類。
總的感覺,又點不倫不類,當然不是說這樣不能用,就是覺得風格不統一。其實,看SAX部分的作用,就是為了用DTD檔案進行XML的校驗,而這種校驗用JDOM或DOM4J也可以完成。所以可以改成JDOM或DOM4J的統一風格,本人將這段程式碼改成DOM4J的方式:
	public static Document getDocument(final InputStream dtd, InputStream xml) throws DocumentException {
		SAXReader reader = new SAXReader();
		reader.setValidation(true);
		reader.setEntityResolver(new EntityResolver() {
			public InputSource resolveEntity(String publicId, String systemId) {
				return new InputSource(dtd);
			}
		});

		return reader.read(xml);
	}
這以看到,程式碼相當簡潔,而完成的功能又完全一樣。這裡的Document是DOM4J裡的Document類,不再引用W3C的Document類,風格相當統一。本人已將MyCat裡XML解析全部修改成DOM4J的方式,程式碼簡潔不少。

上面內容,如有問題,歡迎指正。

相關推薦

JAVA MyCat4 XML解析

通過mycat來學習java了^^。 前一篇講到了load方法: private void load(String dtdFile, String xmlFile) { InputStream dtd = null; InputStream xml =

JAVA MyCat2 單例模式

通過mycat來學習java了^^。 接前一篇:http://blog.csdn.net/john_chang11/article/details/78668667 MycatServer server = MycatServer.getInstance(); 獲取My

JAVA MyCat5 類的載入 Java內省/反射機制 註解Annotation

通過mycat來學習java了^^。 上一篇瞭解了XML解析的四種方式,並對MyCat的原始碼進行了修改,這一篇接著往下看: dtd = XMLRuleLoader.class.getResourceAsStream(dtdFile); x

JAVA MyCat3 關於getResourceAsStream(fileName)的檔案位置

通過mycat來學習java了^^。 前一篇文章介紹了單例模式建立了MycatServer單例項,下面一起看看MycatServer初始化方法的內容: private MycatServer() { // 讀取檔案配置 this.config = ne

FastDFS的配置、部署API使用解讀4FastDFS配置之Client配置

一種方式是通過呼叫ClientGlobal類的初始化方法對配置檔案進行載入,另一種是通過呼叫API逐一設定配置引數。後一種方式對於使用Zookeeper等載入屬性的方式很方便。 1. 載入配置檔案: String configFileName = "conf/dfs-c

java基礎回顧線程以及synchronized關鍵字

dom com stack 相互 ++ 關於 而是 。。 str 本文將從線程的使用方式、源碼、synchronized關鍵字的使用方式和陷阱以及一些例子展開java線程和synchronized關鍵字的內容。 一、線程的概念 線程就是程序中單獨順序的流控制。線程本 身不能

目標檢測分割:SSD

SSD github : https://github.com/weiliu89/caffe/tree/ssd SSD paper : https://arxiv.org/abs/1512.02325 SSD eccv2016 slide pdf : http://d

Java設計模式 原型模式

一、引言        在開發過程中,有時會遇到為一個類建立多個例項的情況,這些例項內部成員往往完全相同或有細微的差異,而且例項的建立開銷比較大或者需要輸入較多引數,如果能通過複製一個已建立的物件例

Java學習總結21——XML文檔解析:DOM解析,SAX解析

Oz 學習總結 AR javax exce 天氣 efault ray XP 一.XML簡介1.可擴展性標記語言(eXtensible Markup Language)2.XML用於描述數據3.應用場合:(1)持久化存儲數據(2)數據交換(3)數據配置4.XML語法(1)文

Java並發4- synchronizedCAS

線程 static ima bubuko nts 就是 incr 獲取 阻塞 引言 上一篇文章中我們說過,volatile通過lock指令保證了可見性、有序性以及“部分”原子性。但在大部分並發問題中,都需要保證操作的原子性,volatile並不具有該功能,這時就需要通過其他

Java併發程式設計4:守護執行緒執行緒阻塞的四種情況

守護執行緒Java中有兩類執行緒:User Thread(使用者執行緒)、Daemon Thread(守護執行緒) 使用者執行緒即執行在前臺的執行緒,而守護執行緒是執行在後臺的執行緒。 守護執行緒作用是為其他前臺執行緒的執行提供便利服務,而且僅在普通、非守護執行緒仍然執行時才需要,比如垃圾回收執行緒就是一個

java基礎筆記4----數組

adding 類型 說明 spa 初始化 pac align int nbsp 介紹: 數組是一種數據類型,是引用類型,是一塊連續的內存空間,用於存儲和管理相同類型的多個數據。 定義:-- > 數組的聲明方式 先聲明,在開辟內存空間--> int [] a;

卷積神經網絡學習筆記心得4池化

設計者 位置 浪費 需要 三種 限制 右移 理論 alt 圖片經過卷積、激活後的結果一般帶有大量原圖信息。 上圖中卷積核提取的是豎直方向上的連續像素,但是,被增強的像素只占了結果的1/3,對於多層網絡,其余重要性較低的信息也被傳入了下一層網絡,造成了不必要的浪費,因此需要

java虛擬機4--類加載機制

sta 代理技術 賦值 工作 開始 外部 equals() ioe con 類加載機制 類是在運行期間第一次使用時動態加載的,而不是編譯時期一次性加載。因為如果在編譯時期一次性加載,那麽會占用很多的內存。 1.1 類的生命周期 包括以下 7 個階段: 加

Java並發4

環境 訪問 obj 元素 dac app ole 可能 最新 java中的線程安全是什麽: 就是線程同步的意思,就是當一個程序對一個線程安全的方法或者語句進行訪問的時候,其他的不能再對他進行操作了,必須等到這次訪問結束以後才能對這個線程安全的方法進行訪問 什麽叫線程安全:

「深入Java虛擬機4」:類加載機制

來講 合並 field 數字 對象 例如 二進制 種類 jar 類加載過程 類從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期包括:加載、驗證、準備、解析、初始化、使用和卸載七個階段。 其中類加載的過程包括了加載、驗證、準備、解析、初始化五個階段。在這五個階段

繼承派生4:二義性三角繼承和菱形繼承

         一般說來,在派生類中對基類成員的訪問應該是唯一的,但是,由於多繼承情況下,可能造成對基類中某成員的訪問出現了不唯一的情況,則稱為對基類成員訪問的二義性問題。  實際上,在上例已經出現過這一問題,回憶一下上例中(參照繼承

使用XWAF框架5——XML解析器:CXDP

       XWAF推出了自己的組合式XML文件解析器,英文名叫:“CXDP”,是“Combined XML Document Parser”的縮寫。核心程式碼屬XWAF原創,註釋、日誌和幫助文件採用全中文描述,特別適合於中文背景的初級程式設計師學

資料結構——排序查詢4——常見的內部排序演算法大全

這篇博文就讓我水一次,這兩天量產部落格,偷個懶,不過下面的文章都是我自己寫的: 插入排序演算法及其分析 簡單的氣泡排序及其分析 希爾排序及其分析 快速排序演算法及其分析 合併排序演算法及其分析 堆排序演算法及其分析 選擇排序演算法及其分析

Java原始碼系列4:String,StringBuilder,StringBuffer區別

hi,國慶節後第一篇。首先,祝大家國慶節快樂,然後祝大家上班快樂。 既然上班了,那就知識學起來,今天咱說一下String,StringBuffer和StringBuilder的區別,這是面試必問,但是如果是工作了的小哥哥和小姐姐,就不會傻白甜的問這個問題,但咱還是要知道的,畢竟要