zoukankan      html  css  js  c++  java
  • 20145107 《Java程序设计》第九周学习总结

    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 ClassLoaderExtension ClassLoaderSystem 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/200 2/2 20/20
    第二周 100/300 1/3 18/38
    第三周 200/500 1/4 22/60
    第四周 250/750 1/5 30/90
    第五周 450/1200 1/6 20/110
    第六周 400/1600 2/8 30/140
    第七周 150/1750 2/10 30/170
    第八周 500/2250 2/12 30/200
    第九周 230/2580 2/14 30/230

    参考资料

  • 相关阅读:
    ios 动画与2D、3D绘图
    ios UI设计与开发 按钮、图标和图片
    算法基础
    快速排序
    ios网络开发 同步下载和异步下载
    用C#调用Execl
    SQL函数大全
    出差
    窗体间的互操作
    垂直滚动条代码
  • 原文地址:https://www.cnblogs.com/20145107lcd/p/5450735.html
Copyright © 2011-2022 走看看