logo头像
ICQL

205_javase

本文于 906 天之前发表,文中内容可能已经过时。

基础

  • 1、jdk、jre
  • 2、classpath:.class文件运行路径,默认为.,即当前目录;可手动设置 set classpath=d:\
  • 3、数据类型:
    • 1)基本类型(均有默认值:整数类型默认值为0,浮点类型默认值为0.0,字符为\u0000,布尔为flase;普通方法里的声明类型后的未赋值变量,不能使用,而类的字段变量未赋值,在new出的对象可以使用,其值为默认值)
      • 整数类型(范围为正负)
        • byte(字节):8bit,2^8=256个,-128~127
        • short(短整型):16bit,2^16=65536
        • int(整型):32bit,默认整数类型都是int,范围为+-21亿级
        • long(长整型):64bit
      • 浮点类型(范围为正负,不精确,会造成数据丢失)
        • float(单精度):32bit
        • double(双精度):64bit,默认小数类型都是double
      • char(字符):16bit(范围为正0~2^16=65536),’’单引号,采用Unicode编码格式,表示一个Unicode字符,所有字符都用两个字节表示,包括中英文,
      • boolean(布尔):不确定,看具体虚拟机实现
    • 2)引用类型:类型,数组
  • 4、数据溢出:数据超过了其表示的范围,会循环表示
  • 5、数据转型:
    • 自动转型:范围由小到大,byte,short,int,long,float,double
    • 强制转型:由大到小,(),F
  • 6、运算符:
    • && 和 & , || 和 |区别:与和或,表示意义一样,双字符有短路功能,检查条件时,前后条件如果前条件满足,后条件直接跳过不检查了,而单字符则都要检查
  • 7、程序结构
    • 顺序结构
    • 选择结构
    • 循环结构:foreach功能,for(int item : int[]类型变量)

面向对象

  • 1、3大特征:封装(数据抽象),继承,多态(方法重载,对象多态:子父对象互转)

  • 2、类型:某类群体的一些基本特征的抽象的概念集合,属于模板;对象则是具体的实例;接口、枚举、注解等都是特殊的类

    • 1)访问权限控制

      • 类型:public,default(默认为空)
      • 类型成员
        • public:可以被所有其他类所访问
        • protected:自身、子类及同一个包中类可以访问
        • default:同一包中的类可以访问,声明时没有加修饰符,认为是friendly
        • private:只能被自己访问和修改
    • 2)构造方法:隐式的是static,名称与类名相同,没有返回值(直接不写返回值类型),一个类中至少有一个构造方法,若缺省,则自动生成一个无参构造方法,若自己定义了构造方法,则不会自动生成

    • 3)关键字

      • static:所有类的实例对象和类共享同一个static成员
        • 字段:表示类变量
        • 方法:表示类方法
      • final:表示不再改变
        • 类:禁止继承此类,由于类是final,则它的方法隐式的是final
        • 字段:一旦赋值则不再允许改变,对于基本类型表示永不改变的编译时常量;对于引用类型指的是这个引用只能指向这个对象,不能改变其指向,但是可以改变它指向的这个对象的值
        • 方法:禁止重写方法,private方法其实隐式的是 final
      • static final:常量
      • this:类内部方法中经常使用,作为当前类的当前实例,使用方法
        • 当前对象:this
        • 当前字段:this.字段名
        • 当前类方法:this.普通方法,this()代表构造方法,多个构造方法时调用其中的构造方法,this();必须放在方法的首句
      • super:
        • super.字段名,父类字段
        • super(),调用父类构造方法,缺省默认会调用父类无参构造方法,同this()一样,必须放在构造方法中的第一行,和this()互相调用的话,至少要保留一个构造方法没有调用this()作为出口,因为这个出口要用来调用父类super()
    • 4)类之间的关系(6种)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      //1)泛化(Generalization)可以简单理解为继承关系
      public class A { ... }
      public class B extends A { ... }

      //2)实现(Realization)一般是指接口和实现类之间的关系
      public interface A {...}
      public class B implements A { ... }

      //3)聚合(Aggregation)是一种包含关系,A 类对象包含 B 类对象,B 类对象的生命周期可以不依赖 A 类对象的生命周期,
      //也就是说可以单独销毁 A 类对象而不影响 B 对象,比如课程与学生之间的关系
      public class A {
      private B b;
      public A(B b) {
      this.b = b;
      }
      }

      //4)组合(Composition)也是一种包含关系。A 类对象包含 B 类对象,B 类对象的生命周期跟依赖 A 类对象的生命周期,
      //B 类对象不可单独存在,比如鸟与翅膀之间的关系
      public class A {
      private B b;
      public A() {
      this.b = new B();
      }
      }

      //5)关联(Association)是一种非常弱的关系,包含聚合、组合两种关系。具体到代码层面,
      //如果 B 类对象是 A 类的成员变量,那 B 类和 A 类就是关联关系


      //6)依赖(Dependency)是一种比关联关系更加弱的关系,包含关联关系。
      //不管是 B 类对象是 A 类对象的成员变量,还是 A 类的方法使用 B 类对象作为参数或者返回值、局部变量,
      //只要 B 类对象和 A 类对象有任何使用关系,我们都称它们有依赖关系。
* 5)主方法:public static void main(String args[]){}
    * public主方法必须是公共的
    * static主方法由类直接调用,执行类:java类名称
    * void主方法是一切的开始,没有返回值
    * main系统规定的主方法名称,执行类默认找到此名称
    * String args[]表示一些运行时的参数,通过字符串接收,在类名后 空格+字符串参数,多个参数用空格区分开,均保存在args[]字符串数组中
* 6)代码块:程序中用'{}'定义起来的程序
    * 普通代码块,方法里用于区分代码
    * 构造代码块,({语句;}),将和所有构造器分别合并为各自的构造器,相当于为实例对象统一初始化
    * 静态代码块,static {//静态代码块;},和编译时将和static字段合并相当于类的构造器
* 7)特殊类型
    * (1) 抽象类
        * 普通类是完整的功能类,可直接产生对象使用,其中方法已经实现完整;而抽象类则只声明了方法而未具体实现,所以要加前缀abstract,抽象方法一定要在抽象类里边,抽象类也用abstract声明
        * 抽象类不能实例化
        * 抽象类必须有子类,使用extend继承,所以不能有final定义,final定义类表示不能被继承(终结)
        * 子类必须重写抽象类的全部抽象方法
        * 抽象类对象可以使用子类对象的向上转型方式
        * 抽象类有构造方法,因为除了抽象方法,普通的字段和方法要实例化
        * 抽象类可以不包含抽象方法
    * (2)接口interface
        * 极度抽象,可以实现"多继承",让实现类可以向上转型为多种不同的类型,接口本身也可以多继承形成新的接口
        * 可以包含字段,而这些字段默认是 public final static,java SE5之前用来 创建全局枚举变量 enum,不能是空白final,必须初始化
        * 接口中方法默认是 public abstrct,而接口本身默认是default
        * 默认接口的访问修饰符是public(一般不写),接口内部的成员访问修饰符也只能是public
    * (3)枚举enum(多例设计模式)
    * (4)注解Annotation(标记)
        * java SE 中的三个注解
            * @Override 重写检查
            * @Deprecated 提醒过期的方法,不建议使用
            * @SuppressWarnings 压制警告信息
    * (5)内部类:在一个类的内部定义了一个类
        * 普通内部类:普通内部类的对象默认持有包含类的一个对象的引用
        * 静态内部类:static,相当于何包含类没有任何关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Message{
public void print();
}
class Demo{
public static void get(Message msg){
msg.print();
}
}
public class TestDemo{
public static void main(String[] args){
Demo.get(new Message(){
public void print(){
System.out.println("Hello World");
}
})
}
}
  • 3、多态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
1.要有继承关系
2.子类要重写父类的方法
3.父类引用指向子类对象

成员变量:编译看左边(父类),运行看左边(父类)
成员方法:编译看左边(父类),运行看右边
静态方法:编译看左边(父类),运行看左边(父类)


* java实现多态的机制,重载(Overloading)是一种多态的表现,重写(Overriding)是父类和子类间的多态表现
* 方法的多态性:重载和重写
* 重写Overriding:方法参数类型,个数,方法名完全一致,发生在继承的子父类中
* 重写以子类为准,且子类重写的方法访问权限不能比父类更小
* 重写方法后,子类想调用父类原来的方法使用 super.方法名
* this.方法 先从子类找方法,找不到就调用父类的
* super.方法 直接调用父类的指定方法
* 父类方法为private,重写不起作用,调用的方法仍然是父类的方法
* 重载Overloading:方法名相同,方法参数类型参数个数不同,发生在一个类中
* 对象的多态性:父子类对象的转换
* 向上转型:子类对象转为父类对象,父类 父类对象 = 子类实例;(自动转型)
* 向下转型:父类对象转为子类对象,子类 子类对象 = (子类)父类实例;(强制转换)
* 注意:如果子类有重写过父类的方法,则不管如何转型,关键看是实例化的是哪个对象,最后调用的一定是实例化的哪个对象的方法
* 对象发生向下转型前,一定要首先发生对象的向上转型,即如果只实例化了父类对象,则强制转换父类为子类对象会报错,因为实例化的对象并没有包含子类的所有成员
* 判断对象是否是某个类型的实例,用表达式 (变量 instanceof 类型)返回值为boolean
* 向上转型用的最多,可以用父类变量作为参数接收所有子类实例,而不需要用重载方法
* 绑定(一般而言只针对方法)
* 静态绑定(编译期绑定):staticfinalprivate也属于final)方法,任何类型的字段
* 又叫前期绑定,在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法)
* 动态绑定(运行时绑定):除去静态绑定之外的方法
* 又叫后期绑定,在运行时根据具体对象的类型进行绑定


class Father {
String name = "父类字段";
String method(){
return "父类方法";
}
static String method1(){
return "父类静态方法";
}
final String method2(){
return "父类final方法";
}
}
public class Son extends Father {
String name = "子类字段";
String method(){
return "子类方法";
}
static String method1(){
return "子类静态方法";
}
public static void main(String[] args) {
Father sample = new Son();
System.out.println("调用的字段:" + sample.name);
System.out.println("调用的方法:" + sample.method());
System.out.println("调用的方法:" + sample.method1());
}
}

/*输出
调用的字段:父类字段
调用的方法:子类方法
调用的方法:父类静态方法

子类实例化后堆中存储的是子类的对象(包括父类的字段,子类的字段),所以第一行输出的是 父类的字段,第二行是普通方法,属于运行时绑定,输出的是子类的方法,第三行static属于编译期绑定(编译后的字节码已确定应该调用父类的方法)
*/
  • 4、异常错误Throwable类

    • 1)Error extends Throwable:指的是jvm错误,运行环境错误或硬件错误,并非程序错误
    • 2)Exception extends Throwable:指的是程序中出现的错误,可以进行异常处理,可以使用Exception类接受所有异常
      • 程序异常处理机制:
        • (1)如果程序出现了异常,那么会自动的由jvm根据异常类型实例化一个指定的异常类的对象
        • (2)如果程序中没有任何的异常处理,则这个异常类的实例化对象将交给jvm进行处理,jvm默认的处理方式:将进行异常信息输出,然后中断程序执行
        • (3)如果程序存在异常处理,会由 try 语句捕获产生的异常类对象
        • (4)然后和 try 后的每一个 catch 进行匹配(相当于传参),如果没有匹配成功,将交给jvm默认处理,如同第2步
        • (5)不管是否有异常,或者异常是否能和 catch 匹配,都会执行 finally 程序
      • RuntimeException 运行时异常(不受检查的异常),Exception的特殊子类
      • 所有catch捕获范围小的异常必须放在catch捕获范围大的异常前
      • throws 关键字:放在方法后面public int div(int x) throws Exception{},表示此方法发生了异常也不会处理(jvm也不会处理),将异常上抛给调用处处理,调用处再利用try catch捕获上抛的异常(注意主方法也可以上抛异常,相当于交给jvm处理异常)
      • throw用于用户手工抛出异常类的实例对象,必须放在try里边,throw new Exception(“随便抛的!”);异常类的实例对象一般由jvm产生
      • 如果try语句中有一个return,则依然先执行finall语句,然后再执行return
  • 5、泛型

    • 通配符 ?
    • 设置上限
      • 类定义:类名称<T extends 类>{}
      • 声明对象:类名称<? extends 类> 对象名
    • 设置下限
      • 类定义:类名称<T super 类>{}
      • 声明对象:类名称<? super 类> 对象名
    • 泛型类
    • 泛型接口
    • 泛型方法
      • 使用泛型方法时,pulbic staticT[] get(T … args){},先要 在前面声明泛型标记,否则无法使用
      • 泛型方法不一定要在泛型类中定义
  • 6、包机制package

    • 包:类似于命名空间,为了统一管理并区分类
    • 常用包:java.lang,java.lang.reflect,java.util,java.tex,java.sql,java.net,java.io,java.awt,javax.swing,java.applet
    • 访问修饰符
      • 类(public 和 friendly默认不写):public任意,friendly只能在同一包中访问
      • 类成员:
        • public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问
        • private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问
        • protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量
        • friendly ,在同一个包中的类可以访问,其他包中的类不能访问
    • 常用命令:
      • javac -d . Test.java -d代表生成文件夹,. 代表当前目录,Test.java 代表java源文件,生成”包.类文件夹形式”
      • 运行 java 包.类
      • 将”包.类文件夹形式”压缩成.jar文件,jar -cvf my.jar 文件夹名称
  • 7、其他语法特性

    • 断言assert:调试使用
    • 不定项参数:使用 (int … data),data实际是数组,在方法里以数组使用,且不定项参数必须放参数列表最后一个
    • foreach:使用语法 for(数据类型 变量 : 数组或者集合){}
    • 静态导入:如果要导入的包.类的全部方法是static,则可以使用 import static 包.类.*
  • 8、值传递or引用传递

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    //1、基本类型和引用类型的不同之处
    int num = 10;
    String str = "hello";

    //变量本身就是一个存储在栈中的值,如num、str
    //基本类型:10这个值直接保存在num变量中,或者说num的值就是10
    //引用类型:str这个变量指向 堆中(字符串常量池)中的"hello"对象,即str指向"hello"对象

    //2、赋值运算符(=)的作用、
    int num = 10;
    String str = "hello";
    num = 20;
    str = "java";

    //对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉
    //对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。如上图所示,"hello" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)

    //3、参数传递基本上就是赋值操作(重要)
    //第一个例子:基本类型
    void foo(int value) {
    value = 100;
    }
    foo(num); // num 没有被改变

    //第二个例子:没有提供改变自身方法的引用类型
    void foo(String text) {
    text = "windows";
    }
    foo(str); // str 也没有被改变

    //第三个例子:提供了改变自身方法的引用类型
    StringBuilder sb = new StringBuilder("iphone");
    void foo(StringBuilder builder) {
    builder.append("4");
    }
    foo(sb); // sb 被改变了,变成了"iphone4"。

    //第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
    StringBuilder sb = new StringBuilder("iphone");
    void foo(StringBuilder builder) {
    builder = new StringBuilder("ipad");
    }
    foo(sb); // sb 没有被改变,还是 "iphone"。


    //4、局部变量/方法参数
    //局部变量和方法参数在jvm中的储存方法是相同的,都是在栈上开辟空间来储存的,随着进入方法开辟,退出方法回收。以32位JVM为例,boolean/byte/short/char/int/float以及引用都是分配4字节空间,long/double分配8字节空间。对于每个方法来说,最多占用多少空间是一定的,这在编译时就可以计算好。我们都知道JVM内存模型中有,stack和heap的存在,但是更准确的说,是每个线程都分配一个独享的stack,所有线程共享一个heap。对于每个方法的局部变量来说,是绝对无法被其他方法,甚至其他线程的同一方法所访问到的,更遑论修改。当我们在方法中声明一个 int i = 0,或者 Object obj = null 时,仅仅涉及stack,不影响到heap,当我们 new Object() 时,会在heap中开辟一段内存并初始化Object对象。当我们将这个对象赋予obj变量时,仅仅是stack中代表obj的那4个字节变更为这个对象的地址。
    //数组类型引用和对象:
    //当我们声明一个数组时,如int[] arr = new int[10],因为数组也是对象,arr实际上是引用,stack上仅仅占用4字节空间,new int[10]会在heap中开辟一个数组对象,然后arr指向它。
    //当我们声明一个二维数组时,如 int[][] arr2 = new int[2][4],arr2同样仅在stack中占用4个字节,会在内存中开辟一个长度为2的,类型为int[]的数组,然后arr2指向这个数组。这个数组内部有两个引用(大小为4字节),分别指向两个长度为4的类型为int的数组。

    //参考自Intopass,链接:https://www.zhihu.com/question/31203609/answer/50992895

lang包常用类

  • Object

  • System

  • Runtime

  • String类

    • 实例化方法2种:
      • 直接赋值:String str = “Hello”;会将字符串对象放入字符串常量池(不在普通的堆内存),而且只占一份内存
      • 构造方法:String str = new String(“Hello”);会创建2个字符串对象,占2份内存空间(都在普通的堆内存中),其中一个是匿名对象”Hello”,在创建出真正的对象后被GC标记为垃圾,创建的真正对象无法自动移动到字符串常量池,必须手动调用intern()方法入池
    • == 所有关系运算符比较的是值的结果,所以类似 == 用于比较对象的时候比较的是对象的存储地址数值是否相等,对象内容比较要重写 equals()方法和hashCode()等方法,利用equals去判断,String类已经重写,故判断Stirng类内容是否相等时,应该使用equals()方法,已经重写过了Object的equals()方法
    • 字符串内容一旦声明,将无法改变,拼接字符串只是创建不同的对象,然后没有变量指向的都将成为垃圾
  • StringBuilder/StringBuffer类:

    • 除非涉及频繁更改字符串以外,优先使用String类
    • StringBuffer和StringBuilder:StringBuffer 字符串变量(线程安全,加了很多保证多线程时的”同步”),StringBuilder 字符串变量(非线程安全,单线程使用),非多线程优先使用StringBuilder (https://blog.csdn.net/rmn190/article/details/1492013)
    • String类没有的方法:reverse()字符串反转,replace(),insert()等
  • 包装类(将基本类型包装成引用类型)

    • 数值型(Number子类):byte(Byte),short(Short),int(Integer),long(Long),float(Float),double(Double)
    • 对象型(Object子类):boolean(Boolean),char(Character)
    • 装箱:基本类型包装成引用类型
    • 拆箱:引用类型变为基本类型
    • jdk1.5之后自动装箱拆箱:Object obj = 15;(int->Integer->Object),int result = (Integer)obj;(Object->Integer->int)
    • 包装类也使用了对象池的概念:类似字符串String,直接赋值会自动入池,使用new Integer(10)只会开辟内存空间存储,必须手动入池
    • == 只能比较基本类型,包装类必须使用equals()
    • 转换类型:利用包装类的方法方便转型:int result = Integer.parseInt(“10.21”);(字符串转为boolean时,只要字符串不是”true”或者”false”时全部按照flase处理)
    • 一般类转字符串:String str = String.valueOf(object objs)
  • 数组:动态初始化 = new String[2],静态初始化 = new String{“1”,”2”}

    • 常用方法:java.util.Array.sort()
  • 日期操作类

    • 日期时间类java.util.Date
      • public Date(),实例化Date类对象,得到的是当前日期
      • public Date(long date)将数字变为Date类对象,long为日期时间数据
      • public long getTime()将当前日期时间变为long型
    • 日期格式化操作类java.text.SimpleDateFormat,非线程安全
      1
      2
      3
      4
      5
      6
      7
      String str = "1981-09-19 12:12:12.123";
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
      Date date = sdf.parse(str);
      //jdk8以上建议使用DateTimeFormatter
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
      LocalDate date = LocalDate.parse("2017 06 17", formatter);
      System.out.println(formatter.format(date));
  • 随机数类 java.util.Random

    • new Random().nextInt(101);
  • 数学公式类:java.lang.Math

  • 大数字操作类(超过double的范围)

    • java.math.BigInteger(Number子类)
    • java.math.BigDecimal(Number子类)
  • 数组操作类java.util.Arrays

  • 比较器(返回0相等,1大于,-1小于)

    • java.lang.Comparable接口,定义类的时候就实现此接口
      • compareTo(T o)方法
      • String类实现了这个接口
    • java.util.Comparator接口,类已经定义好不可更改,则需要另外定义一个比较类,实现此接口去比较
      • compare(T o1, T o2)
      • equals(Object obj)
  • 反射机制 Class类

    • 根据类实例获取”类对象”
      • 1、Object的getClass()方法,基本不用
      • 2、类.class,这个字段是static,由jvm加载类时自己创建的,是一个与”类对象”关联的句柄(编号),Hibernate经常用到
      • 3、Class类内部定义的一个static方法(主要使用)
        • public static Class<?> forName(String className) throws ClassNotFoundException
        • Class.forName()
    • 利用反射实例化一个对象
      • 类型 t = (强转)Class.forName(strClassName).nextInstance();//strClassName通过Class类内部定义的getName()
    • 获取类的成员,通过得到”类对象”,调用类对象的的方法,类对象的类型是Class<?>
      • 调用构造方法 getConstructors(),可实例化对象
      • 调用普通方法 getMethods()
      • 调用字段 getDeclaredFields()
  • 正则表达式

    • ^开始$结束
    • 规则
      • 1表示一位
        • 单个字符
          • a:匹配字母a
          • \:匹配转义字符\
          • \t:匹配转义字符\t
          • \n:匹配转义字符\n
        • 一组字符:匹配里面的任何一个字符
          • [abc]:可能是a,可能是b,可能是c
          • [^abc]:不是a,不是b,不是c
          • [a-zA-Z]:表示全部字母中的任意一个
          • [0-9]:表示全部数字的任意一个
        • 边界匹配:js中使用正则需要
          • ^:一组正则的开始
          • $:一组正则的结束
        • 简写表达式:每一位出现的简写标记也只表示一位
          • .:表示任意的一位字符
          • \d:表示任意一位数字,等价于[0-9]
          • \D:表示任意的一位非数字,等价于[^0-9]
          • \w:表示任意一位的字母、数字、_,等价于[a-zA-Z0-9_]
          • \W:[^a-zA-Z0-9_]
          • \s:这促成任意的一位空格,如\n,\t
          • \S:表示任意的一位非空格
      • 2数量表示
        • ?:0次或1次
        • +:1次或多次
        • *:0次,1次或多次
        • {n}:出现n次
        • {n,}出现n次以上
        • {n,m}出现n次到m次
      • 3逻辑表示
        • 表达式A表达式B:表示A与B
        • 表达式A|表达式B:表示A或B
        • (正则表达式),将多个子表达式合成一个
    • String类对正则的支持(和Pattern,Matcher类的方法大致一样)
      • public boolean matches(String regex)
      • public String replaceAll(String regex,String replacement)
      • public String replaceFirst(String regex,String replacement)
      • public String[] split(String regex)
      • public String[] split(String regex,int limit)//拆成指定个数

JDBC(Java DataBase Connectivity)

  • 使用顺序

    • 1加载数据库驱动:根据classpath找到指定驱动jar包
      • Class.forName(驱动名称);
    • 2数据库连接
      • Connection conn = DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
    • 3数据库操作(见后)
    • 4关闭连接,释放资源
      • conn.close();
  • 元数据

    • 数据库元数据 DatabaseMetaData metaData = conn.getMetaData();获取数据库的一系列信息
    • 参数元数据 PreparedStatement pstmt = conn.prepareStatement(sql);ParameterMetaData p_metaDate = pstmt.getParameterMetaData(); 参数信息
    • 结果集元数据 PreparedStatement pstmt = conn.prepareStatement(sql);ResultSet rs = pstmt.executeQuery();ResultSetMetaData rs_metaData = rs.getMetaData();得到列的信息等
  • 数据库

    • Oracle数据库:

      • 驱动程序包名:ojdbc14.jar
      • 驱动类的名字:oracle.jdbc.driver.OracleDriver
      • JDBC URL:jdbc:oracle:thin:@dbip:port/databasename
        • dbip –为数据库服务器的IP地址,如果是本地可写:localhost或* 127.0.0.1。
        • port –为数据库的监听端口,需要看安装时的配置,缺省为1521。
        • databasename –为数据库的SID,通常为全局数据库的名字。
      • 说明:驱动程序包名有可能会变
    • SQL Server数据库

      • 驱动程序包名:msbase.jar mssqlserver.jar msutil.jar
      • 驱动类的名字:com.microsoft.jdbc.sqlserver.SQLServerDriver
      • JDBC URL:jdbc:microsoft:sqlserver://dbip:port;DatabaseName=databasename
      • 说明:驱动程序包名有可能会变
    • MySQL数据库

      • 驱动程序包名:mysql-connector-java-3.1.11-bin.jar
      • 驱动类的名字:com.mysql.jdbc.Driver
      • JDBC URL:jdbc:mysql://dbip:port/databasename
      • 说明:驱动程序包名有可能会变
  • JDBC:工厂设计模式

    • DriverManager是工厂类,将实例化对象封装在工厂类中,避免不同的数据库厂商 Connection 接口对象直接在客户端中向上转型(紧密耦合),所以使用DriverManager工厂类创建Connection 接口对象,避免紧密耦合
  • Statement接口:操作数据库

    • 通过Connection接口的createStatement()方法实例化
    • 常用方法
      • public int executeUpdate(String sql)
      • public ResultSet executeQuery(String sql)
      • public void close()
    • ResultSet接口结果集
      • 常用方法
        • public boolean next() 移动指针并判断是否有数据
        • public 数据类型 getXxx(列名或列序) 取得指定类型的数据
        • public void close() 关闭结果集
  • PreparedStatement

    • 是 Statement 的子接口
    • 通过Connection接口的 prepareStatement(String sql) 方法实例化
    • 常用方法
      • public int executeUpdate(String sql)
      • public ResultSet executeQuery(String sql)
      • public void set数据类型(int parameterIndex,数据类型 x) 索引编号和数据
      • public void setDate(int parameterIndex,java.sql.Date x)
        • java.util.Date temp = new Date();java.sql.Date bir = new java.sql.Date(temp.getTime())
  • 批处理及事务处理

    • Statement接口事务支持
      • public void addBatch(String sql)
      • public void int[] executeBatch()同时执行多批
    • PreparedStatement”多”增一个方法
      • public void addBatch()用于设置完索引编号和数据后add一次
    • Connection事务支持
      • setAutoCommit(false);取消事务自动提交
      • commit()事务提交
      • rollback()事务回滚
      • 用PreparedStatement时,可创建多个PreparedStatement实例用于不同的更新操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//代码来源网上,只做大致参考
Connection con = null;
PreparedStatement pstm = null;

try {
// 1. 建立与数据库的连接
con = JDBCUtil.getConnection();
// 2. 执行sql语句
// 1).先创建PreparedStatement语句(发送slq请求):
pstm = con.prepareStatement("insert into student values(?,?,?,?)");
con.setAutoCommit(false);//1,首先把Auto commit设置为false,不让它自动提交
// 2) 设置sql语句1
pstm.setInt(1, 33);
pstm.setString(2,"wangqin");
pstm.setString(3, "c++");
pstm.setDouble(4, 78.5);
// 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。
pstm.addBatch();
// 2) 设置sql语句2
pstm.setInt(1, 34);
pstm.setString(2,"wuytun");
pstm.setString(3, "c");
pstm.setDouble(4, 77);
// 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。
pstm.addBatch();
// 2) 设置sql语句3
pstm.setInt(1, 31);
pstm.setString(2,"tetet");
pstm.setString(3, "c++");
pstm.setDouble(4, 90);
// 3) 将一组参数添加到此 PreparedStatement 对象的批处理命令中。
pstm.addBatch();

// 4) 将一批参数提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
pstm.executeBatch();
System.out.println("插入成功!");
// 若成功执行完所有的插入操作,则正常结束
con.commit();//2,进行手动提交(commit)
System.out.println("提交成功!");
con.setAutoCommit(true);//3,提交完成后回复现场将Auto commit,还原为true,

} catch (SQLException e) {
try {
// 若出现异常,对数据库中所有已完成的操作全部撤销,则回滚到事务开始状态
if(!con.isClosed()){
con.rollback();//4,当异常发生执行catch中SQLException时,记得要rollback(回滚);
System.out.println("插入失败,回滚!");
con.setAutoCommit(true);
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
JDBCUtil.closePreparedStatement(pstm);
JDBCUtil.closeConnection(con);
}

网络编程

  • c/s:client/server,开发两套程序,客户端和服务端,较安全

  • b/s:browser/server,只开发服务端程序,客户端使用浏览器 browser 访问,通过公共端口,公共协议,安全性较差

  • 基本实现

    • java.net.ServerSocket类:一个封装了支持TCP协议的操作类,主要工作在服务端,用于接收客户端请求

      • public ServerSocket(int port)开辟一个指定端口监听
      • public Socket accept()服务端接收客户端请求,通过Socket返回
      • public void close()关闭服务器端
    • java.net.Socket类:一个封装了TCP协议的操作类,每一个Socket对象都表示一个客户端

      • public Socket(String host,int port)指定链接的主机的IP地址和端口
      • public OutputStream getOutputStream()取得指定客户端的输出对象,使用时肯定使用 PrintStream 装饰操作
      • public InputStream getInputStream()从指定客户端读取数据,使用Scanner操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//win r 运行telnet,open 172.16.28.42 9999 模拟客户端连接
package com.icql.demo;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.util.Scanner;

public class EchoServer{
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket(9999);
boolean flag;
System.out.println("服务器开始运行......");
flag = true;
while(flag){
final Socket client = server.accept();

new Thread(new Runnable(){
@Override
public void run(){
boolean runFlag = true;
try{
InetAddress addr = client.getInetAddress();
System.out.println("客户端:"+ addr.getHostName() + "\t" + addr.getHostAddress() + "连接成功" );
Scanner scan = new Scanner(client.getInputStream());
PrintStream out = new PrintStream(client.getOutputStream());

while(runFlag){
if(scan.hasNext()){
String str = scan.next();
if("Exit".equalsIgnoreCase(str.trim())){
out.println("Bye!!!");
runFlag = false;
System.out.println("客户端:"+ addr.getHostName() + "/t" + addr.getHostAddress() + "退出连接" );
}
out.println("ECHO:" + str.trim());
}
}
}catch(IOException e){
e.printStackTrace();
}
try{
client.close();
}catch(IOException e){
e.printStackTrace();
}
}
}).start();

}
System.out.println("服务器停止运行......");
server.close();
}
}
微信打赏

赞赏是不耍流氓的鼓励