您的位置:首页 > 编程语言 > Java开发

20145107 《Java程序设计》第九周学习总结

2016-05-02 09:29 666 查看

20145107 《Java程序设计》第九周学习总结

教材学习内容总结

在本周,我们进行了书中第十六,十七,十八章的学习。本周的学习目标是:

了解JDBC架构

掌握JDBC架构

掌握反射与ClassLoader

了解自定义泛型和自定义枚举

会使用标准注解

第十六章:

JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则使用JDBC接口进行操作,本章讲的就是JDBC的一些基础操作。JDBC标准主要分为两个部分:JDBC应用程序开发者接口以及JDBC驱动程序开发者接口。如果你的应用程序需要联机数据库,就是调用JDBC应用开发接口。如果将来要换为Oracle数据库,只要置换Oracle驱动程序。

而厂商在操作JDBC时,可以按照操作方式将驱动程序分为四种类型:

1.JDBC-ODBC Bridge Driver:

这是由微软公司主导的数据库连接标准,基本上,,JDBC是按照ODBC的参考制定而来,所以,ODBC在微软的操作系统上最为成熟,在office Access中的数据库就是使用ODBC。虽然ODBC与JDBC有很多的相同通用之处,但两者并非是一一对应的,所以部分调用无法直接转换因此存在一些功能的限制。

2.Native API Driver:

Native API Driver会以原生的方式条用数据库提供的原生链接库,JDBC的方法调用都会转换为原生链接库中相关的数据库调用。

3.JDBC NET-Driver

这个类型的JDBC驱动程序会将JDBC方法调用转换为特定的网络协议调用,目的是远程与数据库特定的中介服务器或组件进行协议操作。

4.Native Protocol Driver

这种类型的驱动程序的主要作用是将JDBC转化为特定的网络协议,所以此程序也可以使用原生的Java技术来实现,所以,这种类型的驱动程序可以跨平台,在效能上也有很好的表现。

第十七章:

反射:

1.class与class文档:

在Java的程序中,只有真正需要某个类时才会加载对应的.class文档,而不是在程序启动时就加在所有的类。所以大多数的用户只会使用应用程序的部分资源,在需要某些功能的时候才会加载对应的资源,这样可以使程序的运行变得更有效率。

java.lang.Class的实例的代表了Java应用程序运行时加载的.class文档,类,接口编译后哦都会生成相应的.class文档。我们可以使用Object中的getchar()方法,或者是通过class常量取得每个对象对应的class对象。在取得对应的对象后,就可以操作class对象的公开方法取的类的信息就像下面的程序:

package Reflection;

import static java.lang.System.out;

public class ClassInfo {
public static void main(String[] args) {
Class clz = String.class;
out.println("类别名称:" + clz.getName());
out.println("是否为接口:" + clz.isInterface());
out.println("是否为基本类型:" + clz.isPrimitive());
out.println("是否为数组对象:" + clz.isArray());
out.println("父类名称:" + clz.getSuperclass().getName());
}
}

程序运行的程序截图如下:



some类定义了static的区块系统默认首次加载都会执行静态区块,通过在文本模式显示下可以了解如何生成加载.class文件。就像下面的程序:

package Reflection;
public class some {
static {
System.out.println("载入 Some.class 档案");
}
}

package Reflection;

import static java.lang.System.out;

public class SomeDemo {
public static void main(String[] args) {
some s;
out.println("宣告 Some 参考名称");
s = new some();
out.println("生成 Some 实例");
}
}

程序生成图如下所示:



2.使用Class.forName:

在某些应用中,无法实现知道开发人员使用那个类,我们可以使用Class.forName()方法实现加载动态类,可以使用字符串指定名称活的累的相关信息:

package Reflection;

import static java.lang.System.out;

public class InfoAbout {
public static void main(String[] args) {
try {
Class clz = Class.forName(args[0]);
out.println("类的名称:" + clz.getName());
out.println("是否为接口:" + clz.isInterface());
out.println("是否为基本类型:" + clz.isPrimitive());
out.println("是否为数组:" + clz.isArray());
out.println("父类:" + clz.getSuperclass().getName());
} catch (ArrayIndexOutOfBoundsException e) {
out.println("没有指定名称");
} catch (ClassNotFoundException e) {
out.println("找不到指定类别 " + args[0]);
}
}
}

程序运行的截图如下所示:



3.使用class建立对象:

如果知道类的名称,可以使用new关键字建立实例,如果事先不知道类的名称,我们可是使用class.forName()动态加载.class文件,在取得方法后再利用其newInstance来取得实例。这种方法在书中用电影拍摄放映的例子很好的进行了解释。首先,我们先定义出影片链接库该有的功能:

package cc.openhome;

public interface Player {
void play(String video);
}

然后,可以先完成动画的操作播放:

package cc.openhome;

import java.util.Scanner;

public class MediaMaster {
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException {
String playerImpl = System.getProperty("cc.openhome.PlayerImpl");
Player player = (Player) Class.forName(playerImpl).newInstance();
System.out.print("输入想播放的影片:");
player.play(new Scanner(System.in).nextLine());
}
}

在上面的类名称中,并没有把Player的类定义的很固定,这可以再启动程序时通过系统属性来指定,其操作如下:

package cc.openhome;

public class ConsolePlayer implements Player {
@Override
public void play(String video) {
System.out.println("正在播放 " + video);
}
}

建立ClassLoder实例:
JVM的ClassLoader分三层,分别为
Bootstrap ClassLoader
Extension ClassLoader
System ClassLoader
,他们不是类继承的父子关系,是逻辑上的上下级关系。

Bootstrap ClassLoader
是启动类加载器,它是用C++编写的,从
%jre%/lib
目录中加载类,或者运行时用
-Xbootclasspath
指定目录来加载。

Extension ClassLoader
是扩展类加载器,从
%jre%/lib/ext
目录加载类,或者运行时用
-Djava.ext.dirs
制定目录来加载。

System ClassLoader
,系统类加载器,它会从系统环境变量配置的
classpath
来查找路径,环境变量里的.表示当前目录,是通过运行时-classpath或-
Djava.class.path
指定的目录来加载类。

下面有个简单的范例可以指定加载路径,测试class实例是否为同一对象:

package Reflection;

import static java.lang.System.out;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class ClassLoaderDemo {
public static void main(String[] args) {
try {
String path = args[0];
String clzName = args[1];

Class clz1 = loadClassFrom(path, clzName);
out.println(clz1);
Class clz2 = loadClassFrom(path, clzName);
out.println(clz2);

out.printf("clz1 与 clz2 为%s实例",
clz1 == clz2 ? "相同" : "不同");
} catch (ArrayIndexOutOfBoundsException e) {
out.println("沒有指定类别加载路径与名称");
} catch (MalformedURLException e) {
out.println("载入路径错误");
} catch (ClassNotFoundException e) {
out.println("找不到指定的类別");
}
}

private static Class loadClassFrom(String path, String clzName)
throws ClassNotFoundException, MalformedURLException {
ClassLoader loader = new URLClassLoader(new URL[] {new URL(path)});
return loader.loadClass(clzName);
}
}

程序的截图如下:



十八章:

1.自定义泛型:

泛型的本质就是将数据类型也参数化, 普通方法的输入参数的值是可以变的,但是类型(比如: String)是不能变的,它使得了在面对不同类型的输入参数的时候我们要重载方法才行。泛型就是将这个数据类型也搞成跟参数的值一样可以变。

2.自定义枚举:

枚举是一种规范它规范了参数的形式,这样就可以不用考虑类型的不匹配并且显式的替代了int型参数可能带来的模糊概念 枚举像一个类,又像一个数组。Enum作为Sun全新引进的一个关键字,看起来很象是特殊的class, 它也可以有自己的变量,可以定义自己的方法,可以实现一个或者多个接口。枚举具有如下特性:

1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例。

2.所有枚举值都是public , static , final的。注意这一点只是针对于枚举值,我们可以和在普通类里面定义 变量一样定义其它任何类型的非枚举变量,这些变量可以用任何你想用的修饰符。

3.Enum默认实现了java.lang.Comparable接口。

4.Enum覆载了了toString方法,因此我们如果调用Color.Blue.toString()默认返回字符串”Blue”.

5.Enum提供了一个valueOf方法,这个方法和toString方法是相对应的。调用valueOf(“Blue”)将返回Color.Blue.因此我们在自己重写toString方法的时候就要注意到这一点,一把来说应该相对应地重写valueOf方法。

6.Enum还提供了values方法,这个方法使你能够方便的遍历所有的枚举值。

7.Enum还有一个oridinal的方法,这个方法返回枚举值在枚举类种的顺序,这个顺序根据枚举值声明的顺序而定,这里Color.Red.ordinal()返回0。

本周代码托管截图



本周代码链接

本周代码统计截图



学习进度条

代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
目标5000行30篇400小时
第一周200/2002/220/20
第二周100/3001/318/38
第三周200/5001/422/60
第四周250/7501/530/90
第五周450/12001/620/110
第六周400/16002/830/140
第七周150/17502/1030/170
第八周500/22502/1230/200
第九周230/25802/1430/230

参考资料

Java学习笔记(第8版)

《Java学习笔记(第8版)》学习指导

...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: