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