J2SE基础~4
开心一刻: 一辆QQ和一辆玛莎拉蒂追尾,QQ司机大怒:穷逼。你特么开辆破车得瑟啥?所有路人都一愣,不知道QQ司机是哪来的勇气,这时,只见马化腾从QQ里出来… …
下面正式进入干货区,喜欢的话、双击、评论、转发,动一动你的小手让更多的人知道!关注帅比~杨
反射的作用与原理。
泛型常用特点。
解析XML的几种方式的原理与特点:DOM、SAX、PULL。
Java与C++对比。
Java1.7与1.8新特性。
设计模式:单例、工厂、适配器、责任链、观察者等等。
JNI的使用。
1. 反射的作用与原理。
反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。 反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础。
** 反射的用途: **
1> 在运行时获取任意对象所属的类
2> 在运行时构造任意类的对象
3> 在运行时获取任意类所具有的成员变量和方法
核心方法:
成员属性(Field):
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getField(String name)getDeclaredField(String name):获取类的特定属性成员方法(Method):
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法
getDeclaredMethod(String name, Class[] parameterTypes):获得类的特定方法构造方法(Constructor):
getConstructors():获得类的public类型的构造方法。
getDeclaredConstructors():获得类的所有构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法getDeclaredConstructor(Class[] params);获得类的特定方法
2. 泛型常用特点
类型安全:泛 型的主要目标是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就 只存在于程序员的脑海中。Java程序中的一种流行技术是定义这样的集合,即它的元素或键是功能类型的,比如“_列表”。通过在变量声明中捕获这一附加的 类型信息,泛型允许编译器实施这些附加的约束,类型错误现在就可以在编译时被捕获了,而不是在运行时才来进行检测操作。
消除强制类型转换:泛型的一个附带的好处是,消除源代码中的许多强制类型转换,这使得代码更加可读,而且减少了出错的机会。比较两段代码:
不使用泛型的代码段:
List li = new ArrayList();
li.add(new Integer(3));
Integer i = (Integer)li.get(0);
使用泛型:
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
Integer i = li.get(0);
3. 解析XML的几种方式的原理与特点:DOM、SAX、PULL。
———————————————DOM解析xml——————————————
1> 整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能
2> 通过树形结构存取xml文档
3> 可以在树的某个节点上向前或向后移动
缺点:
将整个文档调入内存(包括无用的节点),浪费时间和空间
适用场合:
一旦解析了文档还需多次访问这些数据;硬件资源充足(内存,cpu)
———————————————PULL解析xml——————————————
pull解析器是android内置的解析器,解析原理与sax类似。它提供了类似的事件。如:开始元素和结束元素事件,使用parse.next()可以进入下一个元素并触发相应的事件,事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法获取下一个Text类型节点的值。
pull与sax的不同之处如下:
1> pull读取xml文件后触发相应的事件调用方法返回的是数字。
2> pull可以在程序中控制,想解析到哪里就可以停止到哪里
3> android中推荐使用pull解析
———————————————SAX解析xml——————————————
1> 解析效率高,占用内存少
2> 可以随时停止解析
3> 不能载入整个文档到内存
4> 不能写入xml
5> SAX解析xml文件采用的是事件驱动
4. Java与C++对比。
java是[ sun ]公司开发的。c++是[ 微软公司 ]开发的。
用途不同:C++和JAVA 表面上看,JAVA 比较优秀的地方就是跨平台,也就是程序移植!而C++移植方面不入JAVA,而C++的闪光点,就是程序性能,运行速度,执行效率!C++一般用于开发系统程序,大型程序,驱动等… 对性能要求比较高的东西,而java的闪光点,一般在网页上,或者小型的软件上!但java的执行效率明显不如C++ 因为它要靠java虚拟机运行java编写的程序java程序执行效率不高,但开发效率要比C++要高!
5. Java1.7与1.8新特性。
**ps: ** 如想全面了解jdk新特性可以自行进入官网深入学习,这里只做常用api的介绍。
个人认为比较牛逼的两点Java 1.8新特性如下:
1> 接口中实现具体方法、静态方法。代码如下:
interface Interface_ {
// 普通方法
void v();
// default修饰的具体方法
default void vv() {System.out.println("default void vv()");}
// 静态方法
static void staticMethod(){System.out.println("测试静态方法");}
}
public static void main(String[] args) {
Interface_ i = new Interface_() {
@Override
public void v() {
// TODO Auto-generated method stub
}
@Override
public void vv() {
// TODO Auto-generated method stub
Interface_.super.vv();
System.out.println("Auto-generated method stub");
}
};
i.vv();
Interface_.staticMethod();
}
2> lambda函数和表达式效果如下:
ps: 这个建议直接跑demo看效果,是不是觉得碉堡了呢,如果还不错?还不抓紧关注帅比杨~!
public static void main(String[] args) {
List<String> languages = Arrays.asList("Java", "Scala", "C++","Haskell", "Lisp", "JavaScript");
System.out.println("Languages which starts with J :");
filter(languages, (str) -> ((String) str).startsWith("J"));
System.out.println("Languages which ends with a ");
filter(languages, (str) -> ((String) str).endsWith("a"));
System.out.println("Print all languages :");
filter(languages, (str) -> true);
System.out.println("Print no language : ");
filter(languages, (str) -> false);
System.out.println("Print language whose length greater than 4:");
filter(languages, (str) -> ((String) str).length() > 4);
}
public static void filter(List<String> names, Predicate<String> condition) {
names.stream().filter((name) -> (condition.test(name)))
.forEach((name) -> {
System.out.println(name + " ");
});
}
个人认为比较牛逼的两点Java 1.7新特性如下:
**1>switch中可以使用字串 **
public static void main(String[] args) {
String s = "test";
switch (s) {
case "test":
System.out.println("test");
break;
case "test1":
System.out.println("test1");
break;
default:
System.out.println("break");
break;
}
}
2> 在Java 1.7里,一个catch可以捕获多个异常,这样可以减少重复代码。每个异常之间用 “|” 隔开。
try {
BufferedReader reader = new BufferedReader(new FileReader(""));
Connection con = null;
Statement stmt = con.createStatement();
} catch (IOException | SQLException e) {
e.printStackTrace();
}
6. 设计模式:单例、工厂、适配器、责任链、观察者等等。
设计模式: 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
单例模式(Singleton Pattern)
单例模式约束了一个类的实例化并且确保在JVM中只会存在一个类的实例。这个看起来非常简单的设计模式但是在实现起来的时候会带来很多的实现问题。单例模式的实现在开发中中通常是一个有争议性的话题。看下Singleton Design Pattern文章来了解到实现单例模式的不同方法还有每个方法的优点和缺点。
** 工厂模式(Factory) **
定义:用一个方法去代替构造器或者是new关键字,把创建的对象隐藏起来。
优点如下:
1> 隐蔽了new关键字和构造器
2> 降低了这个对象与别的类之间的耦合度,提高了程序的可扩展性
原因:当子类被别的类替换,或者构造器的参数发生变化的时候,只需改动工厂方 法内的new即可,改动量降到了最低,而如果不用工厂模式,直接用new关键字的话,需要改动的地方就很多了。
3> 把对象的设计和实现分割开来,从而代码扩展性强、灵活性更高。
解决问题:用来解决一个一个类的生成方式过多,容易发生变动,或者是父类和子类之间容易替换的地方。
适配器模式(Adapter Pattern)
适配器设计模式是一个结构型的设计模式,它用于将两个没有关系的接口可以在一起起作用。将这些无关的接口组合在一起的对象就是一个适配器。拿生活中一个实际的场景,我们可以把手机充电器当成是一个适配器因为手机电池需要使用3V的电,但是一般情况下电插板只是产生120V或者240V的电。所以手机充电器就是在手机充电板和正常充电板充当一个适配器的。看下文章Adapter Pattern来看下它是如何在Java中应用的。
责任链模式(Chain of Responsibility Pattern)
责任链模式用于在软件设计中有来自客户端的请求需要传递给一串对象来处理的场景中解耦的。在链中的对象将会决定谁将处理这个情况并且这个请求是否需要传递给链中的下一个对象。我们清楚我们在一个try-cathc代码块中可以有多个catch块。这里每一个catch块都是一种形式的处理器去处理特殊的异常。所以当在try中出现任何异常的时候,它会传递给第一个catch块。如果catch块没办法处理它,它会将情况传递给下个对象。即使最后一个catch块没办法处理它,那么异常将会抛出到链的外面到调用它的程序。
ATM分发机逻辑就是使用了Chain of Responsibility Pattern的实现,看下链接。
观察者模式(Observer Pattern)
观察者模式在你对一个对象的状态感兴趣并且希望在任何时候发生改变的时候都能够得到通知的场景下是很有用的。在观察者模式中,观察其他对象的状态的对象被称为Observer,而被观察的对象被称为Subject。
Java通过java.util.Observable类和java.util.Observer接口提供了内置的观察者模式的实现。的但是因为这个实现非常的简单而且大部分的时候我们不想通过扩展一个类来实现观察者模式因为java不提供类的多继承,所以它被使用的不广泛。
Java消息服务(JMS)使用中介者模式中在介者模式中一块来允许应用来订阅和发布数据到其他的应用中。看文章Observer Pattern来具体的实现和示例程序。
7. JNI的使用。
**概述: **
JNI,是Java Native Interface的缩写,中文为Java本地调用。通俗地说,JNI是一种技术,通过这种技术可以做到以下两点:
1> Java程序中的函数可以调用Native语言写的函数,Native一般指的是C/C++编写的函数。
2> Native程序中的函数可以调用Java层的函数,也就是在C/C++程序中可以调用Java的函数。
JNI 开发流程主要分为以下 6 步:
1> 编写声明了 native 方法的 Java 类
2> 将 Java 源代码编译成 class 字节码文件
3> 用 javah -jni 命令生成.h头文件(javah 是 jdk 自带的一个命令,-jni 参数表示将 class 中用native 声明的函数生成 JNI 规则的函数)
4> 用本地代码实现.h头文件中的函数
5> 将本地代码编译成动态库(Windows:*.dll,linux/unix:*.so,mac os x:*.jnilib)
6> 拷贝动态库至 java.library.path 本地库搜索目录下,并运行 Java 程序
具体流程可以参考这篇文章http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/workflow.html
ps: 喜欢有帮助的话: 双击、评论、转发,动一动你的小手让更多的人知道!关注 帅比-杨