1 NIO簡介 Java Non-blocking IO New IO 2 和傳統IO (1) 面向流 ,面向緩衝區 (2) 阻塞, 非阻塞 (3) 無 選擇器(selector) 3 NIO Buffer:ByteBuffer CharBuffer Channel:FileChannel、ServerSocketChannel 、SocketChannel Selector:選擇器、輪詢器 4 Buffer ByteBuffer CharBuffer ShortBuffer .... 重要屬性 0<=mark<=postion<=limit<=capacity put();//放入數據 get();//獲取數據 flip();//切換爲讀模式 rewind()//能夠重複 mark();//作標記 reset();//返回上一個標記 clear()//清空, compact();//清空,會保留未讀取的數據 間接緩衝區: 堆中,空間不大,速度慢,jvm能夠回收 直接緩衝區: 物理內存(虛擬內存)中,空間大,速度塊,jvm不能回收。 5 Channel FileChannel InputStream OutputStream RandomAcceFile的getChannle(); FileChannel.open(); ServerSocketChannel SocketChannel 6 Selector:選擇器(輪詢器) JUC java.util.concurrent; volitale :易變,不穩定 (1)內存可見性 (2)禁止指令重排序 併發編程中三個特性: (1)互斥性(原子性) (2) 可見性 (3) 禁止指令重排序 synchronized: (1)互斥性 (2)可見性 原子變量: i++ AtomicInteger CAS (Compare And Swap)使用cpu的特殊的指令 Lock 接口 Lock lock=new ReentrantLock(); lock.lock(); try{ }finally{ lock.unlock(); } Condition:條件(隊列) 交替輸出20遍 ABC 併發集合 CopyOnWriteArrayList 有序,能夠重複 CopyOnWriteArraySet 有序,不能重複 ConcurrentHashMap:無序,鍵不能重複 JDK1.7: 分段鎖機制(Segment 16段) 寫入時互斥(段中) ,讀取時共享 ,存儲結構 數組+鏈表 JDK1.8: 採用CAS算法 若是hash位置沒有元素,使用cas放入,若是有元素把第一個節點鎖住,存儲結構: 數組+鏈表+紅黑樹 ArrayBlockingQueue:有界阻塞隊列:同步容器 實現生產者消費者 同步工具類 CountDownLatch:閉鎖,實現當多個線程執行完後,才繼續執行阻塞線程 CyclicBarrier:屏障,實現當多個同時到達後,而後一塊兒執行 Semaphore:信號量,控制併發的線程個數.
1.反射 2.註解 3.XML語言 4.解析XML
1.掌握反射 2.掌握註解 3.瞭解XML語言 4.掌握如何解析xml文檔
需求: 我公司定義了一組接口,而後第三方公司按照我公司的接口實現了一套功能,而後交給咱們,可是咱們公司的項目已經結束,如何實現動態加載第三方公司提供的功能。
反射就是把Java類中的各類成分映射成一個個的Java對象。例如,一個類有:成員變量,方法,構造方法,包等等信息,利用反射技術能夠對一個類進行解剖,把各個組成部分映射成一個個對象。
1.導入java.lang.reflect.*html
2.得到須要操做的類的Java.lang.Class對象java
3.調用Class的方法獲取Field、Method等對象node
4.使用反射API進行操做(設置屬性﹑調用方法)android
第一種方式面試
//方法1:對象.getClass() Student stu=new Student(); Class clazz=stu.getClass();
第二種方式算法
//方法2:類.class clazz= Student.class; clazz=String.class;
第三種方式(推薦)編程
//方法3:Class.forName() clazz=Class.forName("java.lang.String"); clazz=Class.forName("java.util.Date");
Class clazz = Class.forName("java.lang.Object"); Field fields[ ] = clazz.getDeclaredFields();//獲取Field 對象 Method methods[] = clazz.getDeclaredMethods();//獲取Method 對象 Constructor constructors[] = clazz.getDeclaredConstructors();//獲取Constructor對象
方法一:使用Class的newInstance()方法,僅適用於無參構造方法數組
Class clazz=Class.forName("com.qf.reflection.Student"); Object obj=clazz.newInstance();
方法二:調用Constructor的newInstance()方法,適用全部構造方法瀏覽器
Constructor cons = clazz.getConstructor(new Class[]{ String.class, int.class, float.class }); Object obj = cons.newInstance(new Object[ ] {"lkl", 32, 56.5f });
練習一:併發
1 定義Student類,包含:姓名和年齡等屬性,有參和無參構造方法,輸出全部信息的方法
2 使用多種方法生成一個Student類的Class對象
3 使用Class類獲取Student類的屬性並輸出
4 經過有參(無參)構造方法動態建立Student類的對象
調用方法基本步驟:
1.經過Class對象獲取Method 對象
2.調用Method對象的invoke()方法
例如:
Object invoke(Object obj,Object [] args); //object 返回值 //obj 當前方法所屬對象 //args 當前方法的參數列表
操做屬性的基本步驟
1.經過Class對象獲取Field 對象
2.調用Field 對象的方法進行取值或賦值操做
方法 | 說 明 |
---|---|
Xxx getXxx(Object obj) | 獲取基本類型的屬性值 |
Object get(Object obj) ) | 獲得引用類型屬性值 |
void setXxx(Object obj,Xxx val) | 將obj對象的該屬性設置成val值 |
void set(Object obj,object val) | 將obj對象的該屬性設置成val值 |
void setAccessible(boolean flag) | 對獲取到的屬性設置訪問權限 |
優勢:
1.提升了Java程序的靈活性和擴展性,下降了耦合性,提升自適應能力
2.容許程序建立和控制任何類的對象,無需提早硬編碼目標類
缺點:
1.性能問題
2.代碼維護問題
註釋:給代碼添加說明和解釋,註釋幫助開發人員理解程序。(Comment)
註解:給代碼添加說明,這個說明給程序使用。(Annotation)
從 JDK 5.0 開始,Java 增長了對元數據(MetaData) 的支持, 也就是Annotation(註解)。
三個基本的 Annotation:
@Override:限定重寫父類方法, 該註解只能用於方法
@Deprecated:用於表示某個程序元素(類, 方法等)已過期
@SuppressWarnings: 抑制編譯器警告.
什麼是註解
Annotation其實就是代碼裏的特殊標記, 它用於替代配置文件,也就是說,傳統方式經過配置文件告訴類如何運行,有了註解技術後,開發人員能夠經過註解告訴類如何運行。在Java技術裏註解的典型應用是:能夠經過反射技術去獲得類裏面的註解,以決定怎麼去運行類。
註解技術的要點:
如何定義註解
如何反射註解,並根據反射的註解信息,決定如何去運行類
定義新的 Annotation 類型使用@interface關鍵字
聲明註解的屬性
註解屬性的做用:原來寫在配置文件中的信息,能夠經過註解的屬性進行描述。 Annotation的屬性聲明方式:String name(); 屬性默認值聲明方式:Stringname() default 「xxx」; 特殊屬性value:若是註解中有一個名稱value的屬性,那麼使用註解時能夠省略value=部分,如@MyAnnotation(「xxx") 特殊屬性value[];
註解屬性的類型能夠是: String類型 基本數據類型 Class類型 枚舉類型 註解類型 以上類型的一維數組
案例演示1 建立和使用註解
public @interface MyAnnocation { String name(); int num() default 10; MyAnnocation2 anno(); } public @interface MyAnnocation2 { String value(); } public class Demo1 { @MyAnnocation(name="哈哈",num=50,anno=@MyAnnocation2(value = "xxx")) public void show() { System.out.println("xxxxxxx"); } }
元 Annotation指修飾Annotation的Annotation。
@Retention: 只能用於修飾一個 Annotation 定義, 用於指定該 Annotation 能夠保留的域, @Rentention 包含一個 RetentionPolicy 類型的成員變量, 經過這個變量指定域。
RetentionPolicy.CLASS: 編譯器將把註解記錄在 class文件中. 當運行 Java 程序時, JVM 不會保留註解. 這是默認值 RetentionPolicy.RUNTIME:編譯器將把註解記錄在 class文件中. 當運行 Java 程序時, JVM 會保留註解. 程序能夠經過反射獲取該註釋 RetentionPolicy.SOURCE: 編譯器直接丟棄這種策略的註解
@Target:指定註解用於修飾類的哪一個成員.@Target 包含了一個名爲value,類型爲ElementType的成員變量。
@Documented:用於指定被該元 Annotation 修飾的Annotation類將被 javadoc 工具提取成文檔。
@Inherited:被它修飾的 Annotation 將具備繼承性.若是某個類使用了被 @Inherited 修飾的Annotation,則其子類將自動具備該註解。
案例演示2 使用反射獲取註解信息
@Retention(RetentionPolicy.RUNTIME) public @interface PersonInfo { String name(); int age() default 20; String gender(); } public class PersonOpe { @PersonInfo(name="李四",age=20,gender="男") public void show(String name,int age,String gen) { System.out.println(name); System.out.println(age); System.out.println(gen); } } public class Demo2 { public static void main(String[] args) throws Exception{ PersonOpe ope=new PersonOpe(); Class<?> class1=PersonOpe.class; Method method = class1.getMethod("show", String.class,int.class,String.class); PersonInfo annotation = method.getAnnotation(PersonInfo.class); String name=annotation.name(); int age=annotation.age(); String gender=annotation.gender(); method.invoke(ope, name,age,gender); } }
問題1:Windows系統的應用怎麼和Linux系統中的應用交互數據
問題2:其它諸如此類跨平臺、跨操做系統的數據交互問題……
使用XML解決。
可擴展性標記語言(eXtensible Markup Language),文件擴展名.xml
用途:描述、傳輸數據
使用場合:
◦持久化存儲數據
◦數據交換
◦數據配置
示例:persons.xml
<?xml version="1.0" encoding="utf-8" ?> <Person> <ID>1002</ID> <Name>曹操</Name> <Age>20</Age> <!--註釋 --> <ID>1001</ID> <Name>周瑜</Name> <Age>22</Age> </Person>
文檔聲明
在編寫XML文檔時,須要先使用文檔聲明,聲明XML文檔的類型。 最簡單的聲明語法: <?xml version="1.0" ?> 用encoding屬性說明文檔的字符編碼: <?xml version="1.0" encoding="GBK" ?>
元素
XML元素指XML文件中出現的標籤,一個標籤分爲開始標籤和結束標籤,一個標籤有以下幾種書寫形式,例如: 包含標籤體:<a>www.qianfeng.cn</a> 不含標籤體的:<a></a>, 簡寫爲:<a/> 一個標籤中也能夠嵌套若干子標籤。但全部標籤必須合理的嵌套,絕對不容許交叉嵌套 ,例如: <a>welcome to <b>www.qianfeng.org</a></b> 格式良好的XML文檔必須有且僅有一個根標籤,其它標籤都是這個根標籤的子孫標籤。
對於XML標籤中出現的全部空格和換行,XML解析程序都會看成標籤內容進行處理。例如:下面兩段內容的意義是不同的。 <Name> 冰冰 </Name> 和 <Name>冰冰</Name>
一個XML元素能夠包含字母、數字以及其它一些可見字符,但必須遵照下面的一些規範: 1名稱能夠含字母、數字以及其餘的字符 2名稱不能以數字或者標點符號開始 3名稱不能以字符 「xml」(或者 XML、Xml)開始 4名稱不能包含空格 使用瀏覽器驗證文件格式有效性。
屬性
一個標籤能夠有多個屬性,每一個屬性都有它本身的名稱和取值,例如: <Student name="zhangsan"> 屬性值必定要用雙引號(")或單引號(')引發來 定義屬性必須遵循與標籤相同的命名規範 在XML技術中,標籤屬性所表明的信息,也能夠被改爲用子元素的形式來描述,例如: <Student> <name>text</name> </Student>
註釋
Xml文件中的註釋採用:「<!--註釋-->」 格式。 注意: 1 XML聲明以前不能有註釋 2 註釋不能嵌套
格式良好的XML文檔
1必須有XML聲明語句 2必須有且僅有一個根元素 3標籤大小寫敏感 4屬性值用雙引號或單引號 5標籤成對 6元素正確嵌套
上機練習:
使用XML文件描述學生信息
Student( 學號stuNo, 姓名 name, 年齡 age, 班級 clazz )
XML解析方式
◦1 DOM解析
1.1 使用DOM4J(DOM For Java)實現DOM解析
1.2 Java: JAXP技術(廢棄)
◦2 SAX解析(瞭解便可)
Pull解析和Sax相似
DOM和SAX比較
DOM解析 (Document Object Model) 文檔對象模型 易用性強,使用DOM時,將把全部的XML文檔信息都存於內存中,而且遍歷簡單,支持XPath,加強了易用性。 效率低,解析速度慢,內存佔用量太高,對於大文件來講幾乎不可能使用 支持增刪改查 SAX解析(Simple API for Xml) SAX是一個用於處理XML事件驅動的「推」模型,雖然它不是W3C標準,但它倒是一個獲得了普遍承認的API。 SAX模型最大的優勢是內存消耗小 只適合讀取
Dom for java=DOM4J Dom4j是一個簡單、靈活的開放源代碼的庫。Dom4j是一個很是優秀的Java XML API,具備性能優異、功能強大和極易使用的特色。如今不少軟件採用的Dom4j,例如Hibernate,包括sun公司本身的JAXM也用了Dom4j。 使用Dom4j開發,需下載Dom4j相應的jar文件 項目中如何使用DOM4J (1)項目中建立文件夾lib (2)把jar包複製到lib目錄中 (3)右擊jar包--->build path--->add to build path
獲取Document對象
SAXReader reader = new SAXReader(); Document document= reader.read(new File("input.xml"));
節點對象操做
1.獲取文檔的根節點. Element root = document.getRootElement(); 2.取得某個節點的子節點. Element element=node.element(「書名"); 3.取得節點的文字 String text=node.getText(); 4.取得某節點下全部名爲「member」的子節點,並進行遍歷. List nodes = rootElm.elements(「book"); for (Iterator it = nodes.iterator(); it.hasNext();) { Element elm = (Element) it.next(); do something }
節點屬性操做
1.取得某節點下的某屬性 Element root=document.getRootElement(); //屬性名name Attribute attribute=root.attribute("size"); 2.取得屬性的文字 String text=attribute.getText(); 3.刪除某屬性 Attribute attribute=root.attribute("size"); root.remove(attribute);
public static void readxml() throws Exception{ //1建立SaxReader SAXReader reader=new SAXReader(); //2獲取Document對象 Document document=reader.read(new FileReader("src\\books2.xml")); //3獲取根節點 Element root=document.getRootElement();//books //System.out.println(root.getName()); //4獲取book集合 List<Element> bookList=root.elements("book"); for (Element b : bookList) { //System.out.println(b.getName()); //5獲取屬性 String id=b.attributeValue("id"); String name=b.element("name").getText(); String author=b.element("author").getText(); String price=b.elementText("price"); Book book=new Book(Integer.parseInt(id), name, author, Double.parseDouble(price)); System.out.println(book.toString()); } }
//2寫入xml文件 public static void writeXml() throws Exception{ //1 建立SaxReader SAXReader reader=new SAXReader(); //2讀取 Document document=reader.read(new FileReader("src\\books2.xml")); //3獲取根節點 Element root = document.getRootElement(); //4添加節點 Element newbook = root.addElement("book"); //5添加屬性 newbook.addAttribute("id","1003"); //6newbook添加name author price newbook.addElement("name").setText("android開發");; newbook.addElement("author").setText("老張");; newbook.addElement("price").setText("88.8");; //7寫入文件中 OutputFormat format=OutputFormat.createPrettyPrint();//建立一個漂亮的輸出格式 format.setEncoding("utf-8"); XMLWriter writer=new XMLWriter(new FileWriter("src\\books2.xml"), format); writer.write(document); writer.close(); System.out.println("寫入成功"); }
//3 修改和刪除xml文件內容 public static void updateXml() throws Exception{ //1建立Xmlreader SAXReader reader=new SAXReader(); //2文檔 Document document = reader.read(new FileReader("src\\books2.xml")); //3獲取根節點 Element root = document.getRootElement(); //4獲取id=1003的book List<Element> elements = root.elements("book"); Element bookEle = elements.get(2); bookEle.element("name").setText("android從入門到大神"); Element first =elements.get(0); //5刪除 root.remove(first); //6寫入 OutputFormat format=OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer=new XMLWriter(new FileWriter("src\\books2.xml"), format); writer.write(document); writer.close(); System.out.println("修改刪除完畢"); }
1 反射:其實java中一種解剖技術,獲取類中的屬性、方法、構造方法等信息
2 獲取類的類對象
1》建立對象,調用對象的getClass()方法
2》類名.class屬性
3》 Class.forName("類的全名稱");
3 獲取構造方法
Constructor[] cs= class1.getConstructors();
Constructor c2= class1.getConstructor(String.class,int.class,String.class);
c2.newInstance("xxx",20,"男");
4 獲取方法
class1.getMethods();
Method method= class1.getMethod(「show」);
method.invoke(obj);
5 獲取屬性
Field nameField=class1.getDeclaredField("name");
nameField.setAccessable(true);
nameField.set(obj,"xxx");
nameFiled.get(obj);
6 XML 可擴展標記語言
用途:描述 傳輸數據
使用場合: 持久化數據
傳輸數據
配置文件
語法 :
聲明
標籤
屬性
註釋
格式良好的文檔 :
1 必須有聲明
2 標籤區分大小寫
3 有且只有一個根節點
4 屬性值用雙引號和單引號
5 成對出現
6 正確嵌套
xml解析
DOM解析(Document Object Model)
建立DOm樹,易於操做,遍歷 、刪除、修改、寫入
內存大
Sax解析 (Simple API for XML)
Sax只能讀取文件 ,不能刪除 修改
內存小
DOM4J (four for)
1獲取類對象的三種方式
1 設計一個Student類,屬性有:id,name,age,borndate,使用反射建立對象。
2 使用反射調用方法show顯示學生信息。
3 使用反射調用name屬性。
1 簡述Java中的反射使用
2 JAVA經常使用反射API