Java菜鸟教程笔记

 参考:http://www.runoob.com/java/java-tutorial.htmljavascript

Java 基本数据类型html

内置数据类型java

引用类型mysql

Java 变量类型linux

Java 局部变量c++

实例变量git

类变量(静态变量)程序员

Java 修饰符web

默认访问修饰符-不使用任何关键字正则表达式

公有访问修饰符-public

受保护的访问修饰符-protected

访问控制和继承

非访问修饰符

final 修饰符

abstract 修饰符

synchronized 修饰符

transient 修饰符

volatile 修饰符

Java 运算符

短路逻辑运算符

instanceof 运算符

Java运算符优先级

Java 加强 for 循环

Java switch case 语句

Java Number & Math 类

Java Character 类

Java String 类

建立字符串

StringBuffer 方法

建立格式化字符串

String 方法

Java 数组

Arrays 类

Java 日期时间

使用 SimpleDateFormat 格式化日期

使用printf格式化日期

解析字符串为时间

Java 正则表达式

matches 和 lookingAt 方法

replaceFirst 和 replaceAll 方法

appendReplacement 和 appendTail 方法

Java 方法

构造方法

可变参数

finalize() 方法

Java 流(Stream)、文件(File)和IO

读取控制台输入

从控制台读取多字符输入

从控制台读取字符串

控制台输出

读写文件

FileInputStream

FileOutputStream

文件和I/O

Java中的目录

读取目录

删除目录或文件

Java Scanner 类

next() 与 nextLine() 区别

Java 异常处理

Exception 类的层次

Java 内置异常类

异常方法

声明自定义异常

通用异常

Java 继承

继承的特性

构造器(构造方法)

Java 重写(Override)与重载(Overload)

重写(Override)

方法的重写规则

重载(Overload)

重写和重写的区别

Java 多态

多态存在的三个必要条件

虚方法

多态的实现方式

Java 抽象类

抽象方法

抽象类总结规定

Java 封装

封装的优势

实现Java封装的步骤

Java 接口

接口与类类似点

接口与类的区别

接口特性

抽象类和接口的区别

接口的多继承

标记接口

Java 包(package)

包的做用

package 的目录结构

Java 数据结构

枚举(Enumeration)

位集合(BitSet)

向量(Vector)

栈(Stack)

字典(Dictionary)

哈希表(Hashtable)

属性(Properties)

迭代器 iterator 用法

Java 集合框架

Set和List的区别

集合算法

如何使用迭代器

遍历 Map

Java 泛型

泛型方法

泛型类

类型通配符

Java 序列化

序列化对象

反序列化对象

Java 网络编程

Socket 编程

ServerSocket 类的方法

Socket 类的方法

InetAddress 类的方法

Java 发送邮件

Java 多线程编程

一个线程的生命周期

线程的优先级

建立一个线程

经过实现 Runnable 接口来建立线程

经过继承Thread来建立线程

Thread 方法

经过 Callable 和 Future 建立线程

建立线程的三种方式的对比

线程的几个主要概念

多线程的使用

Java Applet 基础

Applet的生命周期

Applet 的调用

Java 文档注释

javadoc 标签

文档注释

javadoc 输出什么

Java 实例

Java 8 新特性

Java MySQL 链接

建立测试数据

链接数据库

Java 9 新特性

 

Java 基本数据类型

内置数据类型

byte

l  byte 数据类型是8位、有符号的,以二进制补码表示的整数;

l  最小值是 -128(-2^7)

l  最大值是 127(2^7-1)

l  默认值是 0

byte 类型用在大型数组中节约空间,主要代替整数,由于 byte 变量占用的空间只有 int 类型的四分之一;

l  例子:byte a = 100,byte b = -50。

 

float

l  float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;

float 在储存大型浮点数组的时候可节省内存空间;

l  默认值是 0.0f

l  浮点数不能用来表示精确的值,如货币;

l  例子:float f1 = 234.5f。

double

l  double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;

l  浮点数的默认类型为double类型;

double类型一样不能表示精确的值,如货币;

l  默认值是 0.0d

l  例子:double d1 = 123.4。

char

l  char类型是一个单一的 16 位 Unicode 字符;

l  最小值是 \u0000(即为0);

l  最大值是 \uffff(即为65,535);

l  char 数据类型能够储存任何字符;

l  例子:char letter = 'A';。

 

引用类型

l  在Java中,引用类型的变量很是相似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,好比 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。

对象、数组都是引用数据类型。

全部引用类型的默认值都是null。

l  一个引用变量能够用来引用任何与之兼容的类型。

l  例子:Site site = new Site("Runoob")。

 

byte,short,char—> int —> long—> float —> double

数据类型转换必须知足以下规则:

l  1. 不能对boolean类型进行类型转换。

l  2. 不能把对象类型转换成不相关类的对象。

l  3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。

l  4. 转换过程当中可能致使溢出或损失精度,例如:

l  5. 浮点数到整数的转换是经过舍弃小数获得,而不是四舍五入,例如:

(int)23.7 == 23;        (int)-45.89f == -45

隐含强制类型转换

1. 整数的默认类型是 int。

l  2. 浮点型不存在这种状况,由于在定义 float 类型时必须在数字后面跟上 F 或者 f。

 

Java 变量类型

Java语言支持的变量类型有:

l  类变量:独立于方法以外的变量,用 static 修饰。

l  实例变量:独立于方法以外的变量,不过没有 static 修饰。

l  局部变量:类的方法中的变量。

public class Variable{     static int allClicks=0;    // 类变量     String str="hello world";  // 实例变量     public void method(){         int i =0;  // 局部变量     } }

Java 局部变量

l  局部变量声明在方法、构造方法或者语句块中;

l  局部变量在方法、构造方法、或者语句块被执行的时候建立,当它们执行完成后,变量将会被销毁;

访问修饰符不能用于局部变量;

l  局部变量只在声明它的方法、构造方法或者语句块中可见;

l  局部变量是在栈上分配的。

l  局部变量没有默认值,因此局部变量被声明后,必须通过初始化,才可使用

实例变量

l  实例变量声明在一个类中,但在方法、构造方法和语句块以外;

l  当一个对象被实例化以后,每一个实例变量的值就跟着肯定;

l  实例变量在对象建立的时候建立,在对象被销毁的时候销毁;

l  实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部可以经过这些方式获取实例变量信息;

l  实例变量能够声明在使用前或者使用后;

访问修饰符能够修饰实例变量;

l  实例变量对于类中的方法、构造方法或者语句块是可见的。通常状况下应该把实例变量设为私有。经过使用访问修饰符可使实例变量对子类可见;

实例变量具备默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值能够在声明时指定,也能够在构造方法中指定;

实例变量能够直接经过变量名访问。但在静态方法以及其余类中,就应该使用彻底限定名:ObejectReference.VariableName。

类变量(静态变量)

l  类变量也称为静态变量,在类中以static关键字声明,但必须在方法构造方法和语句块以外。

不管一个类建立了多少个对象,类只拥有类变量的一份拷贝。

静态变量除了被声明为常量外不多使用。常量是指声明为public/private,final和static类型的变量。常量初始化后不可改变。

l  静态变量储存在静态存储区。常常被声明为常量,不多单独使用static声明变量。

静态变量在第一次被访问时建立,在程序结束时销毁。

l  与实例变量具备类似的可见性。但为了对类的使用者可见,大多数静态变量声明为public类型。

l  默认值和实例变量类似。数值型变量默认值是0,布尔型默认值是false,引用类型默认值是null。变量的值能够在声明的时候指定,也能够在构造方法中指定。此外,静态变量还能够在静态语句块中初始化。

l  静态变量能够经过:ClassName.VariableName的方式访问。

l  类变量被声明为public static final类型时,类变量名称通常建议使用大写字母。若是静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致。

 

Java 修饰符

修饰符

当前类

同一包内

子孙类(同一包)

子孙类(不一样包)

其余包

public

Y

Y

Y

Y

Y

protected

Y

Y

Y

Y/N(说明

N

default

Y

Y

Y

N

N

private

Y

N

N

N

N

默认访问修饰符-不使用任何关键字

default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

使用默认访问修饰符声明的变量和方法,对同一个包内的类是可见的。接口里的变量都隐式声明为 public static final,而接口里的方法默认状况下访问权限为 public

公有访问修饰符-public

被声明为 public 的类、方法、构造方法和接口可以被任何其余类访问。

若是几个相互访问的 public 类分布在不一样的包中,则须要导入相应 public 类所在的包。因为类的继承性,类全部的公有方法和变量都能被其子类继承。

如下函数使用了公有访问控制:

public static void main(String[] arguments) {    // ...}

Java 程序的 main() 方法必须设置成公有的,不然,Java 解释器将不能运行该类。

受保护的访问修饰符-protected

protected 是最难理解的一种 Java 类成员访问权限修饰词,更多详细内容请查看 Java protected 关键字详解

protected 须要从如下两个点来分析说明:

l  子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其余类访问;

子类与基类不在同一包中:那么在子类中,子类实例能够访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

接口及接口的成员变量和成员方法不能声明为 protected。 

访问控制和继承

请注意如下方法继承的规则(只能降级):

父类中声明为 public 的方法在子类中也必须为 public。

父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。

l  父类中声明为 private 的方法,不可以被继承。

非访问修饰符

为了实现一些其余的功能,Java 也提供了许多非访问修饰符。

static 修饰符,用来修饰类方法和类变量。

final 修饰符,用来修饰类、方法和变量,final 修饰的类不可以被继承,修饰的方法不能被继承类从新定义,修饰的变量为常量,是不可修改的。

abstract 修饰符,用来建立抽象类和抽象方法。

synchronized 和 volatile 修饰符,主要用于线程的编程

final 修饰符

final 变量:

final 表示"最后的、最终的"含义,变量一旦赋值后,不能被从新赋值。被 final 修饰的实例变量必须显式指定初始值。

final 修饰符一般和 static 修饰符一块儿使用来建立类常量。

final 方法

类中的 final 方法能够被子类继承,可是不能被子类修改。

声明 final 方法的主要目的是防止该方法的内容被修改。

abstract 修饰符

抽象类:

抽象类不能用来实例化对象,声明抽象类的惟一目的是为了未来对该类进行扩充。

一个类不能同时被 abstract 和 final 修饰。若是一个类包含抽象方法,那么该类必定要声明为抽象类,不然将出现编译错误。

抽象类能够包含抽象方法和非抽象方法。

抽象方法

抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。

抽象方法不能被声明成 final 和 static。

任何继承抽象类的子类必须实现父类的全部抽象方法,除非该子类也是抽象类。

若是一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类能够不包含抽象方法。

抽象方法的声明以分号结尾,例如:public abstract sample();

synchronized 修饰符

synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符能够应用于四个访问修饰符。

transient 修饰符

序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。

该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

volatile 修饰符

volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中从新读取该成员变量的值。并且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任什么时候刻,两个不一样的线程老是看到某个成员变量的同一个值。

一个 volatile 对象引用多是 null。

 

Java 运算符

短路逻辑运算符

当使用与逻辑运算符时,在两个操做数都为true时,结果才为true,可是当获得第一个操做为false时,其结果就一定是false,这时候就不会再判断第二个操做了。

instanceof 运算符

该运算符用于操做对象实例,检查该对象是不是一个特定类型(类类型或接口类型)。

instanceof运算符使用格式以下:

( Object reference variable ) instanceof  (class/interface type)

若是运算符左侧变量所指的对象,是操做符右侧类或接口(class/interface)的一个对象,那么结果为真。

下面是一个例子:

String name = "James";boolean result = name instanceof String; // 因为 name 是 String 类型,因此返回真

Java运算符优先级

一元

+ + - !〜

从右到左

 

条件

?:

从右到左

赋值

= + = - = * = / =%= >> = << =&= ^ = | =

从右到左

 

Java 加强 for 循环

Java5 引入了一种主要用于数组的加强型 for 循环。

Java 加强 for 循环语法格式以下:

for(声明语句 : 表达式){    //代码句子}int [] numbers = {10, 20, 30, 40, 50};       for(int x : numbers ){          System.out.print( x );          System.out.print(","); }

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其做用域限定在循环语句块,其值与此时数组元素的值相等。

表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

 

Java switch case 语句

switch case 执行时,必定会先进行匹配,匹配成功返回当前 case 的值,再根据是否有 break,判断是否继续输出,或是跳出判断。

若是 case 语句块中没有 break 语句时,JVM 并不会顺序输出每个 case 对应的返回值,而是继续匹配,匹配不成功则返回默认 case。

若是当前匹配成功的 case 语句块没有 break 语句,则从当前 case 开始,后续全部 case 的值都会输出,若是后续的 case 语句块有 break 语句则会跳出判断。

 

Java Number & Math 类

全部的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。

当 x 被赋为整型值时,因为x是一个对象,因此编译器要对x进行装箱。而后,为了使x能进行加运算,因此要对x进行拆箱。

Math 的方法都被定义为 static 形式,经过 Math 类能够在主函数中直接调用。

序号

方法与描述

1

xxxValue()

将 Number 对象转换为xxx数据类型的值并返回。

2

compareTo()

将number对象与参数比较。

3

equals()

判断number对象是否与参数相等。

4

valueOf()

返回一个 Number 对象指定的内置数据类型

5

toString()

以字符串形式返回值。

6

parseInt()

将字符串解析为int类型。

 

10

rint()

返回与参数最接近的整数。返回类型为double。

intValue() :以 int 形式返回指定的数值。

 

Integer valueOf(int i)返回一个表示指定的 int 值的 Integer 实例。

Integer valueOf(String s):返回保存指定的 String 的值的 Integer 对象。

Integer valueOf(String s, int radix): 返回一个 Integer 对象,该对象中保存了用第二个参数提供的基数进行解析时从指定的 String 中提取的值。

Integer b = Integer.valueOf("444",16);   // 使用 16 进制,=1092

 

Java Character 类

将一个char类型的参数传递给须要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。 这种特征称为装箱,反过来称为拆箱

序号

方法与描述

1

isLetter()

是不是一个字母

2

isDigit()

是不是一个数字字符

3

isWhitespace()

是不是一个空白字符

4

isUpperCase()

是不是大写字母

5

isLowerCase()

是不是小写字母

6

toUpperCase()

指定字母的大写形式

7

toLowerCase()

指定字母的小写形式

8

toString()

返回字符的字符串形式,字符串的长度仅为1

 

Java String 类

建立字符串

建立字符串最简单的方式以下:

String greeting = "菜鸟教程";

在代码中遇到字符串常量时,这里的值是 "菜鸟教程"",编译器会使用该值建立一个 String 对象。

和其它对象同样,可使用关键字和构造方法来建立 String 对象。

String 类有 11 种构造方法,这些方法提供不一样的参数来初始化字符串,好比提供一个字符数组参数:

注意:String 类是不可改变的,因此你一旦建立了 String 对象,那它的值就没法改变了(详看笔记部分解析)。

若是须要对字符串作不少修改,那么应该选择使用 StringBuffer & StringBuilder 类

StringBuffer 方法

如下是 StringBuffer 类支持的主要方法:

序号

方法描述

1

public StringBuffer append(String s)

将指定的字符串追加到此字符序列。

2

public StringBuffer reverse()

 将此字符序列用其反转形式取代。

3

public delete(int start, int end)

移除此序列的子字符串中的字符。

4

public insert(int offset, int i)

将 int 参数的字符串表示形式插入此序列中。

5

replace(int start, int end, String str)

使用给定 String 中的字符替换此序列的子字符串中的字符。

建立格式化字符串

咱们知道输出格式化数字可使用 printf() 和 format() 方法。

String 类使用静态方法 format() 返回一个String 对象而不是 PrintStream 对象。

String 类的静态方法 format() 能用来建立可复用的格式化字符串,而不只仅是用于一次打印输出。

以下所示:

System.out.printf("浮点型变量的值为 " +                   "%f, 整型变量的值为 " +                   " %d, 字符串变量的值为 " +                   "is %s", floatVar, intVar, stringVar);//你也能够这样写String fs;fs = String.format("浮点型变量的值为 " +                    "%f, 整型变量的值为 " +                    " %d, 字符串变量的值为 " +                    " %s", floatVar, intVar, stringVar);

String 方法

下面是 String 类支持的方法,更多详细,参看 Java String API 文档:

SN(序号)

方法描述

1

char charAt(int index)

返回指定索引处的 char 值。

2

int compareTo(Object o)

把这个字符串和另外一个对象比较。

3

int compareTo(String anotherString)

按字典顺序比较两个字符串。

4

int compareToIgnoreCase(String str)

按字典顺序比较两个字符串,不考虑大小写。

5

String concat(String str)

将指定字符串链接到此字符串的结尾。

6

boolean contentEquals(StringBuffer sb)

当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。

7

static String copyValueOf(char[] data)

返回指定数组中表示该字符序列的 String。

 

9

boolean endsWith(String suffix)

测试此字符串是否以指定的后缀结束。

10

boolean equals(Object anObject)

将此字符串与指定的对象比较。

11

boolean equalsIgnoreCase(String anotherString)

将此 String 与另外一个 String 比较,不考虑大小写。

 

16

int indexOf(int ch)

返回指定字符在此字符串中第一次出现处的索引。

17

int indexOf(int ch, int fromIndex)

返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。

18

int indexOf(String str)

 返回指定子字符串在此字符串中第一次出现处的索引。

19

int indexOf(String str, int fromIndex)

返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。

 

21

int lastIndexOf(int ch)

 返回指定字符在此字符串中最后一次出现处的索引。

22

int lastIndexOf(int ch, int fromIndex)

返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。

23

int lastIndexOf(String str)

返回指定子字符串在此字符串中最右边出现处的索引。

24

int lastIndexOf(String str, int fromIndex)

 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。

25

int length()

返回此字符串的长度。

26

boolean matches(String regex)

告知此字符串是否匹配给定的正则表达式。

 

29

String replace(char oldChar, char newChar)

返回一个新的字符串,它是经过用 newChar 替换此字符串中出现的全部 oldChar 获得的。

30

String replaceAll(String regex, String replacement)

使用给定的 replacement 替换此字符串全部匹配给定的正则表达式的子字符串。

31

String replaceFirst(String regex, String replacement)

 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

32

String[] split(String regex)

根据给定正则表达式的匹配拆分此字符串。

33

String[] split(String regex, int limit)

根据匹配给定的正则表达式来拆分此字符串。

34

boolean startsWith(String prefix)

测试此字符串是否以指定的前缀开始。

35

boolean startsWith(String prefix, int toffset)

测试此字符串从指定索引开始的子字符串是否以指定前缀开始。

36

CharSequence subSequence(int beginIndex, int endIndex)

 返回一个新的字符序列,它是此序列的一个子序列。

37

String substring(int beginIndex)

返回一个新的字符串,它是此字符串的一个子字符串。

38

String substring(int beginIndex, int endIndex)

返回一个新字符串,它是此字符串的一个子字符串。

39

char[] toCharArray()

将此字符串转换为一个新的字符数组。

40

String toLowerCase()

使用默认语言环境的规则将此 String 中的全部字符都转换为小写。

41

String toLowerCase(Locale locale)

 使用给定 Locale 的规则将此 String 中的全部字符都转换为小写。

42

String toString()

 返回此对象自己(它已是一个字符串!)。

43

String toUpperCase()

使用默认语言环境的规则将此 String 中的全部字符都转换为大写。

44

String toUpperCase(Locale locale)

使用给定 Locale 的规则将此 String 中的全部字符都转换为大写。

45

String trim()

 

Java 数组

注意: 建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员可以快速理解java语言。

java 里面为何数组都须要new一下?而C++不须要

java 数组所引用的值,是在堆里的,

java 数组是引用对象,引用对象都须要开辟内存空间,

new 关键字在java里是实例化对象,也是为对象开辟内存空间

其实也不必定要new, int[] arr = {}; 这样也是能够的

若是大括号里不赋值,就是个空数组,大括号里赋几个值,这个数组就是多大

c / c++ 也是这样用

int arr1[] = {1,2,3,4,5,6}; 

int arr2[50] = {-23,34,56,100,234,-9,0,45,10002};

只是,c/c++ 声明时能够指定大小,

JAVA 里面的数组名是一个引用变量,引用变量是放在是放在一个栈里面,而JAVA数组自己就是对象,Java中对象是在堆中的,所以数组不管保存原始类型仍是其余对象类型,数组对象自己是在堆中的。因此若是不new一下,就没法获得这个数组,即引用变量没有引用的对象。而在C++中,数组名其实是数组的首地址,是一个指针,数组在声明以后就已经生成了这个数组对象。就不用new了

 

下面的语句首先声明了一个数组变量 myList,接着建立了一个包含 10 个 double 类型元素的数组,而且把它的引用赋值给 myList 变量。

// 数组大小      int size = 10;      // 定义数组      double[] myList = new double[size];      myList[0] = 5.6;//……

 

 

引用和指针的区别?

指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。

本质:引用是别名,指针是地址,具体的:

①从现象上看,指针在运行时能够改变其所指向的值,而引用一旦和某个对象绑定后就再也不改变。这句话能够理解为:指针能够被从新赋值以指向另外一个不一样的对象。可是引用则老是指向在初始化时被指定的对象,之后不能改变,可是指定的对象其内容能够改变。

②从内存分配上看,程序为指针变量分配内存区域,而不为引用分配内存区域,由于引用声明时必须初始化,从而指向一个已经存在的对象。引用不能指向空值。

注:标准没有规定引用要不要占用内存,也没有规定引用具体要怎么实现,具体随编译器 http://bbs.csdn.net/topics/320095541

③ 从编译上看,程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,所以指针能够改变指向的对象(指针变量中的值能够改),而引用对象不能改。这是使用指针不安全而使用引用安全的主要缘由。从某种意义上来讲引用能够被认为是不能改变的指针。

④不存在指向空值的引用这个事实,意味着使用引用的代码效率比使用指针的要高。由于在使用引用以前不须要测试它的合法性。相反,指针则应该老是被测试,防止其为空。

⑤理论上,对于指针的级数没有限制,可是引用只能是一级

 

Arrays 类

java.util.Arrays 类能方便地操做数组,它提供的全部方法都是静态的。

具备如下功能:

l  给数组赋值:经过 fill 方法。

l  对数组排序:经过 sort 方法,按升序。

l  比较数组:经过 equals 方法比较数组中元素值是否相等。

l  查找数组元素:经过 binarySearch 方法能对排序好的数组进行二分查找法操做。

 

Java 日期时间

序号

方法和描述

1

boolean after(Date date)

若当调用此方法的Date对象在指定日期以后返回true,不然返回false。

2

boolean before(Date date)

若当调用此方法的Date对象在指定日期以前返回true,不然返回false。

3

Object clone( )

返回此对象的副本。

4

int compareTo(Date date)

比较当调用此方法的Date对象和指定日期。二者相等时候返回0。调用对象在指定日期以前则返回负数。调用对象在指定日期以后则返回正数。

5

int compareTo(Object obj)

若obj是Date类型则操做等同于compareTo(Date) 。不然它抛出ClassCastException。

6

boolean equals(Object date)

当调用此方法的Date对象和指定日期相等时候返回true,不然返回false。

7

long getTime( )

返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。

8

int hashCode( )

 返回此对象的哈希码值。

9

void setTime(long time)

 

用自1970年1月1日00:00:00 GMT之后time毫秒数设置时间和日期。

10

String toString( )

把此 Date 对象转换为如下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。

使用 SimpleDateFormat 格式化日期

Date dNow = new Date( );SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");System.out.println("当前时间为: " + ft.format(dNow));

使用printf格式化日期

printf 方法能够很轻松地格式化时间和日期。使用两个字母格式,它以 %t 开头而且如下面表格中的一个字母结尾。

转  换  符

说    明

示    例

c

包括所有日期和时间信息

星期六 十月 27 14:21:20 CST 2007

F

"年-月-日"格式

2007-10-27

D

"月/日/年"格式

10/27/07

r

"HH:MM:SS PM"格式(12时制)

02:25:51 下午

T

"HH:MM:SS"格式(24时制)

14:28:16

R

"HH:MM"格式(24时制)

14:28

解析字符串为时间

SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。

 

Java 正则表达式

java.util.regex 包主要包括如下三个类:

Pattern 类:

pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要建立一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式做为它的第一个参数。

Matcher 类:

Matcher 对象是对输入字符串进行解释和匹配操做的引擎。与Pattern 类同样,Matcher 也没有公共构造方法。你须要调用 Pattern 对象的 matcher 方法来得到一个 Matcher 对象。

PatternSyntaxException

PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

注意:在 Java 中正则表达式中则须要有两个反斜杠才能被解析为其余语言中的转义做用。也能够简单的理解在 Java 的正则表达式中,两个 \\ 表明其余语言中的一个 \,这也就是为何表示一位数字的正则表达式是 \\d,而表示一个普通的反斜杠是 \\\\。

根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其余字符转义。所以必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将致使编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\\(hello\\)"。

      // 按指定模式在字符串查找       String line = "This order was placed for QT3000! OK?";       String pattern = "(\\D*)(\\d+)(.*)";       // 建立 Pattern 对象       Pattern r = Pattern.compile(pattern);       // 如今建立 matcher 对象       Matcher m = r.matcher(line);

 

matches 和 lookingAt 方法

matches 和 lookingAt 方法都用来尝试匹配一个输入序列模式。它们的不一样是 matches 要求整个序列都匹配,而lookingAt 不要求。

lookingAt 方法虽然不须要整句都匹配,可是须要从第一个字符开始匹配。

 

replaceFirst 和 replaceAll 方法

replaceFirst 和 replaceAll 方法用来替换匹配正则表达式的文本。不一样的是,replaceFirst 替换首次匹配,replaceAll 替换全部匹配。

 

appendReplacement 和 appendTail 方法

Matcher 类也提供了appendReplacement 和 appendTail 方法用于文本替换

 

Java 方法

 System.out.println(),那么它是什么呢?

l  println() 是一个方法。

l  System 是系统类。

l  out 是标准输出对象。

 

命令行参数的使用

有时候你但愿运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

命令行参数是在执行程序时候紧跟在程序名字后面的信息。

public class CommandLine {    public static void main(String args[]){        for(int i=0; i<args.length; i++){          System.out.println("args[" + i + "]: " + args[i]);       }    }}$ javac CommandLine.java  $ java CommandLine this is a command line 200 -100 args[0]: this args[1]: is args[2]: a args[3]: command args[4]: line args[5]: 200 args[6]: -100

 

构造方法

当一个对象被建立时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值。

一般会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来建立一个完整的对象。

无论你是否自定义构造方法,全部的类都有构造方法,由于Java自动提供了一个默认构造方法,默认构造方法的访问修改符和类的访问修改符相同(类为 public,构造函数也为 public;类改成 private,构造函数也改成 private)。

一旦你定义了本身的构造方法,默认构造方法就会失效。

 

可变参数

JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。

方法的可变参数的声明以下所示:

typeName... parameterName

在方法声明中,在指定参数类型后加一个省略号(...) 。

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它以前声明。

public class VarargsDemo {     public static void main(String args[]) {         // 调用可变参数的方法         printMax(34, 3, 3, 2, 56.5);         printMax(new double[]{1, 2, 3});     }      public static void printMax( double... numbers) {         if (numbers.length == 0) {             System.out.println("No argument passed");             return;         }         double result = numbers[0];         for (int i = 1; i <  numbers.length; i++){             if (numbers[i] >  result) {                 result = numbers[i];             }         }         System.out.println("The max value is " + result);     } }

 

finalize() 方法

Java 容许定义这样的方法,它在对象被垃圾收集器析构(回收)以前调用,这个方法叫作 finalize( ),它用来清除回收对象

例如,你可使用 finalize() 来确保一个对象打开的文件被关闭了。

在 finalize() 方法里,你必须指定在对象销毁时候要执行的操做。

finalize() 通常格式是:

protected void finalize(){    // 在这里终结代码}

关键字 protected 是一个限定符,它确保 finalize() 方法不会被该类之外的代码调用。

固然,Java 的内存回收能够由 JVM 来自动完成。若是你手动使用,则可使用上面的方法。

 

Java 流(Stream)、文件(File)和IO

http://www.runoob.com/java/java-files-io.html

读取控制台输入

Java 的控制台输入由 System.in 完成。

为了得到一个绑定到控制台的字符流,你能够把 System.in 包装在一个 BufferedReader 对象中来建立一个字符流。

下面是建立 BufferedReader 的基本语法:

BufferedReader br = new BufferedReader(new                        InputStreamReader(System.in));

BufferedReader 对象建立后,咱们即可以使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。

 

从控制台读取多字符输入

从 BufferedReader 对象读取一个字符要使用 read() 方法,它的语法以下:

int read( ) throws IOException

每次调用 read() 方法,它从输入流读取一个字符并把该字符做为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。

 

从控制台读取字符串

从标准输入读取一个字符串须要使用 BufferedReader 的 readLine() 方法。

它的通常格式是:

String readLine( ) throws IOException

JDK 5 后的版本咱们也可使用 Java Scanner 类来获取控制台的输入。

 

控制台输出

在此前已经介绍过,控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用。

PrintStream 继承了 OutputStream类,而且实现了方法 write()。这样,write() 也能够用来往控制台写操做。

PrintStream 定义 write() 的最简单格式以下所示:

void write(int byteval)

该方法将 byteval 的低八位字节写到流中。

注意:write() 方法不常用,由于 print() 和 println() 方法用起来更为方便。

 

读写文件

如前所述,一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。

 

FileInputStream

该流用于从文件读取数据,它的对象能够用关键字 new 来建立。

有多种构造方法可用来建立对象。

可使用字符串类型的文件名来建立一个输入流对象来读取文件:

InputStream f = new FileInputStream("C:/java/hello");

也可使用一个文件对象来建立一个输入流对象来读取文件。咱们首先得使用 File() 方法来建立一个文件对象:

File f = new File("C:/java/hello");InputStream out = new FileInputStream(f);

 

FileOutputStream

该类用来建立一个文件并向文件中写数据

若是该流在打开文件进行输出前,目标文件不存在,那么该流会建立该文件。

有两个构造方法能够用来建立 FileOutputStream 对象。

使用字符串类型的文件名来建立一个输出流对象:

OutputStream f = new FileOutputStream("C:/java/hello")

也可使用一个文件对象来建立一个输出流来写文件。咱们首先得使用File()方法来建立一个文件对象:

File f = new File("C:/java/hello"); OutputStream f = new FileOutputStream(f);

 

文件和I/O

还有一些关于文件和I/O的类,咱们也须要知道:

File Class(类)

FileReader Class(类)

FileWriter Class(类)

 

Java中的目录

建立目录:

File类中有两个方法能够用来建立文件夹:

mkdir( )方法建立一个文件夹,成功则返回true,失败则返回false。失败代表File对象指定的路径已经存在,或者因为整个路径还不存在,该文件夹不能被建立。

mkdirs()方法建立一个文件夹和它的全部父文件夹。

注意:linux文件路径分隔符为 /  ,windows的文件路径分隔符为  \ 。 Java 在 UNIX 和 Windows 自动按约定分辨文件路径分隔符。若是你在 Windows 版本的 Java 中使用分隔符 (/) ,路径依然可以被正确解析。

 

 

读取目录

一个目录其实就是一个 File 对象,它包含其余文件和文件夹。

若是建立一个 File 对象而且它是一个目录,那么调用 isDirectory() 方法会返回 true。

能够经过调用该对象上的 list() 方法,来提取它包含的文件和文件夹的列表。

 

删除目录或文件

删除文件可使用 java.io.File.delete() 方法。

如下代码会删除目录 /tmp/java/,须要注意的是当删除某一目录时,必须保证该目录下没有其余文件才能正确删除,不然将删除失败。

 

Java Scanner 类

java.util.Scanner 是 Java5 的新特征,咱们能够经过 Scanner 类来获取用户的输入。

下面是建立 Scanner 对象的基本语法:

Scanner s = new Scanner(System.in);

接下来咱们演示一个最简单的数据输入,并经过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符串,在读取前咱们通常须要 使用 hasNext 与 hasNextLine 判断是否还有输入的数据

 

next() 与 nextLine() 区别

next():

l  一、必定要读取到有效字符后才能够结束输入。

l  二、对输入有效字符以前遇到的空白,next() 方法会自动将其去掉。

l  三、只有输入有效字符后才将其后面输入的空白做为分隔符或者结束符

l  next() 不能获得带有空格的字符串。

nextLine():

l  一、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车以前的全部字符。

l  二、能够得到空白。

 

Java 异常处理

要理解Java异常处理是如何工做的,你须要掌握如下三种类型的异常:

检查性异常:最具表明的检查性异常是用户错误或问题引发的异常,这是程序员没法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

运行时异常: 运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常能够在编译时被忽略。

错误: 错误不是异常,而是脱离程序员控制的问题。错误在代码中一般被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

 

Exception 类的层次

全部的异常类是从 java.lang.Exception 类继承的子类。

Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。

Java 程序一般不捕获错误。错误通常发生在严重故障时,它们在Java程序处理的范畴以外。

Error 用来指示运行时环境发生的错误。

例如,JVM 内存溢出。通常地,程序不会从错误中恢复。

异常类有两个主要的子类:IOException 类和 RuntimeException 类。

 

在 Java 内置类中(接下来会说明),有大部分经常使用检查性和非检查性异常。

 

Java 内置异常类

Java 语言定义了一些异常类在 java.lang 标准包中。

标准运行时异常类的子类是最多见的异常类。因为 java.lang 包是默认加载到全部的 Java 程序的,因此大部分从运行时异常类继承而来的异常均可以直接使用。

Java 根据各个类库也定义了一些其余的异常,下面的表中列出了 Java 的非检查性异常。

 

异常方法

下面的列表是 Throwable 类的主要方法:

序号

方法及说明

1

public String getMessage()

返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。

2

public Throwable getCause()

返回一个Throwable 对象表明异常缘由。

3

public String toString()

使用getMessage()的结果返回类的串级名字。

4

public void printStackTrace()

打印toString()结果和栈层次到System.err,即错误输出流。

5

public StackTraceElement [] getStackTrace()

返回一个包含堆栈层次的数组。下标为0的元素表明栈顶,最后一个元素表明方法调用堆栈的栈底。

6

public Throwable fillInStackTrace()

用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。

 

注意下面事项:

l  catch 不能独立于 try 存在。

l  在 try/catch 后面添加 finally 块并不是强制性要求的。

l  try 代码后不能既没 catch 块也没 finally 块。

l  try, catch, finally 块之间不能添加任何代码。

 

声明自定义异常

在 Java 中你能够自定义异常。编写本身的异常类时须要记住下面的几点。

l  全部异常都必须是 Throwable 的子类。

l  若是但愿写一个检查性异常类,则须要继承 Exception 类。

l  若是你想写一个运行时异常类,那么须要继承 RuntimeException 类。

 

通用异常

在Java中定义了两种类型的异常和错误。

JVM(Java虚拟机) 异常:由 JVM 抛出的异常或错误。例如:NullPointerException 类,ArrayIndexOutOfBoundsException 类,ClassCastException 类。

程序级异常:由程序或者API程序抛出的异常。例如 IllegalArgumentException 类,IllegalStateException 类。

 

 

Java 继承

 

继承的特性

l  子类拥有父类非 private 的属性、方法。

l  子类能够拥有本身的属性和方法,即子类能够对父类进行扩展。

l  子类能够用本身的方式实现父类的方法。

l  Java 的继承是单继承,可是能够多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 A 类继承 B 类,B 类继承 C 类,因此按照关系就是 C 类是 B 类的父类,B 类是 A 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

l  提升了类之间的耦合性(继承的缺点,耦合度高就会形成代码之间的联系越紧密,代码独立性越差)。

 

inal关键字

final 关键字声明类能够把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

l  声明类:

final class 类名 {//类体}

l  声明方法:

修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

:实例变量也能够被定义为 final,被定义为 final 的变量不能被修改。被声明为 final 类的方法自动地声明为 final,可是实例变量并非 final

 

构造器(构造方法)

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。若是父类的构造器带有参数,则必须在子类的构造器中显式地经过 super 关键字调用父类的构造器并配以适当的参数列表。

若是父类构造器没有参数,则在子类的构造器中不须要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

 

Java 重写(Override)与重载(Overload)

重写(Override)

重写是子类对父类的容许访问的方法的实现过程进行从新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类能够根据须要,定义特定于本身的行为。 也就是说子类可以根据须要实现父类的方法。

重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如: 父类的一个方法申明了一个检查异常 IOException,可是在重写这个方法的时候不能抛出 Exception 异常,由于 Exception 是 IOException 的父类,只能抛出 IOException 的子类异常。

class Animal{    public void move(){       System.out.println("动物能够移动");    } } class Dog extends Animal{    public void move(){       System.out.println("狗能够跑和走");    }    public void bark(){       System.out.println("狗能够吠叫");    } } public class TestDog{    public static void main(String args[]){       Animal a = new Animal(); // Animal 对象       Animal b = new Dog(); // Dog 对象       a.move();// 执行 Animal 类的方法       b.move();//执行 Dog 类的方法       b.bark();//报错    } }

以上实例编译运行结果以下:

TestDog.java:30: cannot find symbol symbol  : method bark() location: class Animal                 b.bark();

 

方法的重写规则

l  参数列表必须彻底与被重写方法的相同;

l  返回类型必须彻底与被重写方法的返回类型相同;

访问权限不能比父类中被重写的方法的访问权限更低。例如:若是父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。

父类的成员方法只能被它的子类重写。

l  声明为final的方法不能被重写。

声明为static的方法不能被重写,可是可以被再次声明。

l  子类和父类在同一个包中,那么子类能够重写父类全部方法,除了声明为private和final的方法。

l  子类和父类不在同一个包中,那么子类只可以重写父类的声明为public和protected的非final方法。

重写的方法可以抛出任何非强制异常,不管被重写的方法是否抛出异常。可是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更普遍的强制性异常,反之则能够。

构造方法不能被重写。

l  若是不能继承一个方法,则不能重写这个方法。

 

重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不一样。返回类型能够相同也能够不一样。

每一个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最经常使用的地方就是构造器的重载。

重载规则:

l  被重载的方法必须改变参数列表(参数个数或类型不同);

l  被重载的方法能够改变返回类型;

被重载的方法能够改变访问修饰符;

被重载的方法能够声明新的或更广的检查异常;

l  方法可以在同一个类中或者在一个子类中被重载。

没法以返回值类型做为重载函数的区分标准。

 

重写和重写的区别

方法的重写(Overriding)和重载(Overloading)是java多态性的不一样表现,重写是父类与子类之间多态性的一种表现,重载能够理解成多态的具体表现形式。

l  (1)方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不一样或数量相同而类型和次序不一样,则称为方法的重载(Overloading)。

l  (2)方法重写是在子类存在方法与父类的方法的名字相同,并且参数的个数与类型同样,返回值也同样的方法,就称为重写(Overriding)。

l  (3)方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

 

Java 多态

 

多态是同一个行为具备多个不一样表现形式或形态的能力。

多态就是同一个接口,使用不一样的实例而执行不一样操做

多态性是对象多种表现形式的体现。

现实中,好比咱们按下 F1 键这个动做:

l  若是当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;

l  若是当前在 Word 下弹出的就是 Word 帮助;

l  在 Windows 下弹出的就是 Windows 帮助和支持。

同一个事件发生在不一样的对象上会产生不一样的结果。

多态存在的三个必要条件

l  继承

l  重写

l  父类引用指向子类对象

 

虚方法

咱们将介绍在Java中,当设计类时,被重写的方法的行为怎样影响多态性。

咱们已经讨论了方法的重写,也就是子类可以重写父类的方法。

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字super。

public class Employee{}public class Salary extends Employee{}Salary s = new Salary("员工 A", "北京", 3, 3600.00);Employee e = new Salary("员工 B", "上海", 2, 2400.00);s.mailCheck(); e.mailCheck(); //运行时调用Salary 类中的 mailCheck() 方法。

在编译的时候,编译器使用 Employee 类中的 mailCheck() 方法验证该语句, 可是在运行的时候,Java虚拟机(JVM)调用的是 Salary 类中的 mailCheck() 方法。

Java中全部的方法都能以这种方式表现,所以,重写的方法能在运行时调用,无论编译的时候源代码中引用变量是什么数据类型。

Java虚方法你能够理解为java里全部被overriding的方法都是virtual的,全部重写的方法都是override的。

虚方法就是java类在继承中,在上转型中,java类对象实际调用的方法是子类重写的方法;也就是编译器和jvm调用的不是同一个类的方法;

 

多态的实现方式

方式一:重写:

这个内容已经在上一章节详细讲过,就再也不阐述,详细可访问:Java 重写(Override)与重载(Overload)

方式二:接口

l  1. 生活中的接口最具表明性的就是插座,例如一个三接头的插头都能接在三孔插座中,由于这个是每一个国家都有各自规定的接口规则,有可能到国外就不行,那是由于国外本身定义的接口类型。

l  2. java中的接口相似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体能够看 java接口 这一章节的内容。

方式三:抽象类和抽象方法

 

Java 抽象类

在面向对象的概念中,全部的对象都是经过类来描绘的,可是反过来,并非全部的类都是用来描绘对象的,若是一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

抽象类除了不能实例化对象以外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类同样。

因为抽象类不能实例化对象,因此抽象类必须被继承,才能被使用。也是由于这个缘由,一般在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,可是因为父类自己是抽象的,因此不能使用这些方法。

在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却能够实现多个接口。

 

抽象方法

若是你想设计这样一个类,该类包含一个特别的成员方法,该方法的具体实现由它的子类肯定,那么你能够在父类中声明该方法为抽象方法。

Abstract 关键字一样能够用来声明抽象方法,抽象方法只包含一个方法名,而没有方法体。

抽象方法没有定义,方法名后面直接跟一个分号,而不是花括号。

public abstract double computePay();

声明抽象方法会形成如下两个结果:

若是一个类包含抽象方法,那么该类必须是抽象类。

任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

继承抽象方法的子类必须重写该方法。不然,该子类也必须声明为抽象类。最终,必须有子类实现该抽象方法,不然,从最初的父类到最终的子类都不能用来实例化对象。

 

抽象类总结规定

l  1. 抽象类不能被实例化(初学者很容易犯的错),若是被实例化,就会报错,编译没法经过。只有抽象类的非抽象子类能够建立对象。

l  2. 抽象类中不必定包含抽象方法,可是有抽象方法的类一定是抽象类。

l  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。

l  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。

l  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

 

Java 封装

在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装能够被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须经过严格的接口控制。

封装最主要的功能在于咱们能修改本身的实现代码,而不用修改那些调用咱们代码的程序片断。

适当的封装可让程式码更容易理解与维护,也增强了程式码的安全性。

 

封装的优势

l  1. 良好的封装可以减小耦合。

l  2. 类内部的结构能够自由修改。

l  3. 能够对成员变量进行更精确的控制。

l  4. 隐藏信息,实现细节。

 

实现Java封装的步骤

1. 修改属性的可见性来限制对属性的访问(通常限制为private)

2. 对每一个值属性提供对外的公共方法访问,也就是建立一对赋取值方法,用于对私有属性的访问(getter和setter方法)

 

Java 接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口一般以interface来声明。一个类经过继承接口的方式,从而来继承接口的抽象方法。

接口并非类,编写接口的方式和类很类似,可是它们属于不一样的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,不然该类要定义接口中的全部方法。

接口没法被实例化,可是能够被实现。一个实现接口的类,必须实现接口内所描述的全部方法,不然就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们能够成为一个空指针,或是被绑定在一个以此接口实现的对象。

 

接口与类类似点

l  一个接口能够有多个方法。

l  接口文件保存在 .java 结尾的文件中,文件名使用接口名。

l  接口的字节码文件保存在 .class 结尾的文件中。

l  接口相应的字节码文件必须在与包名称相匹配的目录结构中。

 

接口与类的区别

l  接口不能用于实例化对象。

l  接口没有构造方法。

接口中全部的方法必须是抽象方法。

接口不能包含成员变量,除了 static 和 final 变量。

l  接口不是被类继承了,而是要被类实现。

l  接口支持多继承。

 

接口特性

接口中每个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其余修饰符都会报错)。

l  接口中能够含有变量,可是接口中的变量会被隐式的指定为 public static final 变量(而且只能是 public,用 private 修饰会报编译错误)。

l  接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

 

抽象类和接口的区别

l  1. 抽象类中的方法能够有方法体,就是能实现方法的具体功能,可是接口中的方法不行。

l  2. 抽象类中的成员变量能够是各类类型的,而接口中的成员变量只能是 public static final 类型的。

l  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是能够有静态代码块和静态方法。

l  4. 一个类只能继承一个抽象类,而一个类却能够实现多个接口。

 

重写接口中声明的方法时,须要注意如下规则:

类在实现接口的方法时,不能抛出强制性异常,只能在接口中,或者继承接口的抽象类中抛出该强制性异常。

l  类在重写方法时要保持一致的方法名,而且应该保持相同或者相兼容的返回值类型。

l  若是实现接口的类是抽象类,那么就不必实现该接口的方法。

在实现接口的时候,也要注意一些规则:

l  一个类能够同时实现多个接口。

l  一个类只能继承一个类,可是能实现多个接口。

l  一个接口能继承另外一个接口,这和类之间的继承比较类似。

 

接口的多继承

在Java中,类的多继承是不合法,但接口容许多继承。

在接口的多继承中extends关键字只须要使用一次,在其后跟着继承接口。 以下所示:

public interface Hockey extends Sports, Event

以上的程序片断是合法定义的子接口,与类不一样的是,接口容许多继承,而 Sports及 Event 可能定义或是继承相同的方法

 

标记接口

最经常使用的继承接口是没有包含任何方法的接口。

标记接口是没有任何方法和属性的接口.它仅仅代表它的类属于一个特定的类型,供其余代码来测试容许作一些事情。

标记接口做用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

没有任何方法的接口被称为标记接口。标记接口主要用于如下两种目的:

创建一个公共的父接口:

正如EventListener接口,这是由几十个其余接口扩展的Java API,你可使用一个标记接口来创建一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

向一个类添加数据类型:

这种状况是标记接口最初的目的,实现标记接口的类不须要定义任何接口方法(由于标记接口根本就没有方法),可是该类经过多态性变成一个接口类型。

 

Java 包(package)

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

包的做用

l  一、把功能类似或相关的类或接口组织在同一个包中,方便类的查找和使用。

l  二、如同文件夹同样,包也采用了树形目录的存储方式。同一个包中的类名字是不一样的,不一样的包中的类的名字是能够相同的,当同时调用两个不一样包中相同类名的类时,应该加上包名加以区别。所以,包能够避免名字冲突。

l  三、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

 

若是在一个包中,一个类想要使用本包中的另外一个类,那么该包名能够省略。

注意:类文件中能够包含任意数量的 import 声明。import 声明必须在包声明以后,类声明以前。

 

package 的目录结构

类放在包中会有两种主要的结果:

l  包名成为类名的一部分,正如咱们前面讨论的同样。

l  包名必须与相应的字节码所在的目录结构相吻合。

一般,一个公司使用它互联网域名的颠倒形式来做为它的包名.例如:互联网域名是 runoob.com,全部的包名都以 com.runoob 开头。包名中的每个部分对应一个子目录。

 

 

Java 数据结构

Java工具包提供了强大的数据结构。在Java中的数据结构主要包括如下几种接口和类:

l  枚举(Enumeration)

l  位集合(BitSet)

l  向量(Vector)

l  栈(Stack)

l  字典(Dictionary)

l  哈希表(Hashtable)

l  属性(Properties)

序号

类描述

1

Vector 

该类和ArrayList很是类似,可是该类是同步的,能够用在多线程的状况,该类容许设置默认的增加长度,默认扩容方式为原来的2倍。

2

Stack 

栈是Vector的一个子类,它实现了一个标准的后进先出的栈。

3

Dictionary 

Dictionary 类是一个抽象类,用来存储键/值对,做用和Map类类似。

4

Hashtable 

Hashtable 是 Dictionary(字典) 类的子类,位于 java.util 包中。

5

Properties 

Properties 继承于 Hashtable,表示一个持久的属性集,属性列表中每一个键及其对应值都是一个字符串。

6

BitSet

一个Bitset类建立一种特殊类型的数组来保存位值。BitSet中数组大小会随须要增长。

枚举(Enumeration)

枚举(Enumeration)接口虽然它自己不属于数据结构,但它在其余数据结构的范畴里应用很广。 枚举(The Enumeration)接口定义了一种从数据结构中取回连续元素的方式。

例如,枚举定义了一个叫nextElement 的方法,该方法用来获得一个包含多元素的数据结构的下一个元素。

关于枚举接口的更多信息,请参见枚举(Enumeration)

位集合(BitSet)

位集合类实现了一组能够单独设置和清除的位或标志。

该类在处理一组布尔值的时候很是有用,你只须要给每一个值赋值一"位",而后对位进行适当的设置或清除,就能够对布尔值进行操做了。

关于该类的更多信息,请参见位集合(BitSet)

向量(Vector)

向量(Vector)类和传统数组很是类似,可是Vector的大小能根据须要动态的变化。

和数组同样,Vector对象的元素也能经过索引访问。

使用Vector类最主要的好处就是在建立对象的时候没必要给对象指定大小,它的大小会根据须要动态的变化。

关于该类的更多信息,请参见向量(Vector)

栈(Stack)

栈(Stack)实现了一个后进先出(LIFO)的数据结构。

你能够把栈理解为对象的垂直分布的栈,当你添加一个新元素时,就将新元素放在其余元素的顶部。

当你从栈中取元素的时候,就从栈顶取一个元素。换句话说,最后进栈的元素最早被取出。

关于该类的更多信息,请参见栈(Stack)

堆栈除了包括由Vector定义的全部方法,也定义了本身的一些方法。

序号

方法描述

1

boolean empty() 

测试堆栈是否为空。

2

Object peek( )

查看堆栈顶部的对象,但不从堆栈中移除它。

3

Object pop( )

移除堆栈顶部的对象,并做为此函数的值返回该对象。

4

Object push(Object element)

把项压入堆栈顶部。

5

int search(Object element)

返回对象在堆栈中的位置,以 1 为基数。

 

字典(Dictionary)

字典(Dictionary) 类是一个抽象类,它定义了键映射到值的数据结构。

当你想要经过特定的键而不是整数索引来访问数据的时候,这时候应该使用Dictionary。

因为Dictionary类是抽象类,因此它只提供了键映射到值的数据结构,而没有提供特定的实现。

关于该类的更多信息,请参见字典( Dictionary)

Dictionary类已通过时了。在实际开发中,你能够实现Map接口来获取键/值的存储功能。

 

哈希表(Hashtable)

Hashtable类提供了一种在用户定义键结构的基础上来组织数据的手段。

例如,在地址列表的哈希表中,你能够根据邮政编码做为键来存储和排序数据,而不是经过人名。

哈希表键的具体含义彻底取决于哈希表的使用情景和它包含的数据。

关于该类的更多信息,请参见哈希表(HashTable)

Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。

然而,Java 2 重构的Hashtable实现了Map接口,所以,Hashtable如今集成到了集合框架中。它和HashMap类很类似,可是它支持同步。

像HashMap同样,Hashtable在哈希表中存储键/值对。当使用一个哈希表,要指定用做键的对象,以及要连接到该键的值。

 

属性(Properties)

Properties 继承于 Hashtable.Properties 类表示了一个持久的属性集.属性列表中每一个键及其对应值都是一个字符串。

Properties 类被许多Java类使用。例如,在获取环境变量时它就做为System.getProperties()方法的返回值。

关于该类的更多信息,请参见属性(Properties)

 

迭代器 iterator 用法

Java 中的 Iterator 功能比较简单,而且只能单向移动:

l   (1) 使用方法 iterator() 要求容器返回一个 Iterator。第一次调用 Iterator 的 next() 方法时,它返回序列的第一个元素。注意:iterator() 方法是 java.lang.Iterable 接口,被 Collection 继承。

l   (2) 使用 next() 得到序列中的下一个元素。

l   (3) 使用 hasNext() 检查序列中是否还有元素。

l   (4) 使用 remove() 将迭代器新返回的元素删除。

 

Java 集合框架

 

从上面的集合框架图能够看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另外一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,经常使用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

集合框架是一个用来表明和操纵集合的统一架构。全部的集合框架都包含以下内容:

接口:是表明集合的抽象数据类型。例如 Collection、List、Set、Map 等。之因此定义多个接口,是为了以不一样的方式操做集合对象

实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap

算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是由于相同的方法能够在类似的接口上有着不一样的实现。

 

 

Set和List的区别

l  1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,能够重复的元素。

l  2. Set检索效率低下,删除和插入效率高,插入和删除不会引发元素位置改变 <实现类有HashSet,TreeSet>

l  3. List和数组相似,能够动态增加,根据实际存储的数据的长度自动增加List的长度。查找元素效率高,插入删除效率低,由于会引发其余元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。

 

集合算法

集合框架定义了几种算法,可用于集合和映射。这些算法被定义为集合类的静态方法。

在尝试比较不兼容的类型时,一些方法可以抛出 ClassCastException异常。当试图修改一个不可修改的集合时,抛出UnsupportedOperationException异常。

集合定义三个静态的变量:EMPTY_SET,EMPTY_LIST,EMPTY_MAP的。这些变量都不可改变。

 

如何使用迭代器

一般状况下,你会但愿遍历一个集合中的元素。例如,显示集合中的每一个元素。

通常遍历数组都是采用for循环或者加强for,这两个方法也能够用在集合框架,可是还有一种方法是采用迭代器遍历集合框架,它是一个对象,实现了Iterator 接口或ListIterator接口。

迭代器,使你可以经过循环来获得或删除集合的元素。ListIterator 继承了Iterator,以容许双向遍历列表和修改元素。

 

遍历 Map

import java.util.*;public class Test{      public static void main(String[] args) {       Map<String, String> map = new HashMap<String, String>();       map.put("1", "value1");       map.put("2", "value2");       map.put("3", "value3");       //第一种:广泛使用,二次取值       System.out.println("经过Map.keySet遍历key和value:");       for (String key : map.keySet()) {        System.out.println("key= "+ key + " and value= " + map.get(key));       }       //第二种       System.out.println("经过Map.entrySet使用iterator遍历key和value:");       Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();       while (it.hasNext()) {        Map.Entry<String, String> entry = it.next();        System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());       }       //第三种:推荐,尤为是容量大时       System.out.println("经过Map.entrySet遍历key和value");       for (Map.Entry<String, String> entry : map.entrySet()) {        System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());       }       //第四种       System.out.println("经过Map.values()遍历全部的value,但不能遍历key");       for (String v : map.values()) {        System.out.println("value= " + v);       }      }}

 

总结

Java集合框架为程序员提供了预先包装的数据结构和算法来操纵他们。

集合是一个对象,可容纳其余对象的引用。集合接口声明对每一种类型的集合能够执行的操做。

集合框架的类和接口均在java.util包中。

任何对象加入集合类后,自动转变为Object类型,因此在取出的时候,须要进行强制类型转换。

 

Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制容许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操做的数据类型被指定为一个参数。

假定咱们有这样一个需求:写一个排序方法,可以对整型数组、字符串数组甚至其余任何类型的数组进行排序,该如何实现?

答案是可使用 Java 泛型

使用 Java 泛型的概念,咱们能够写一个泛型方法来对一个对象数组排序。而后,调用该泛型方法来对整型数组、浮点数数组、字符串数组等进行排序。

 

泛型方法

你能够写一个泛型方法,该方法在调用时能够接收不一样类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每个方法调用。

下面是定义泛型方法的规则:

l  全部泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型以前(在下面例子中的<E>)。

l  每个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。

l  类型参数能被用来声明返回值类型,而且能做为泛型方法获得的实际参数类型的占位符。

l  泛型方法体的声明和其余方法同样。注意类型参数只能表明引用型类型,不能是原始类型(像int,double,char的等)。

public static < E > void printArray( E[] inputArray ){}  //extends"在通常意义上的意思是"extends"(类)或者"implements"(接口) public static <T extends Comparable<T>> T maximum(T x, T y, T z) {}

 

泛型类

泛型类的声明和非泛型类的声明相似,除了在类名后面添加了类型参数声明部分。

和泛型方法同样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。由于他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。

public class Box<T> {……}

 

类型通配符

一、类型通配符通常是使用?代替具体的类型参数。例如 List<?> 在逻辑上是List<String>,List<Integer> 等全部List<具体类型实参>的父类。

        List<String> name = new ArrayList<String>();         List<Integer> age = new ArrayList<Integer>();         List<Number> number = new ArrayList<Number>(); public static void getData(List<?> data) {……}   

解析: 由于getData()方法的参数是List类型的,因此name,age,number均可以做为这个方法的实参,这就是通配符的做用

二、类型通配符上限经过形如 List<? extends Number>来定义,如此定义就是通配符泛型值接受Number及其下层子类类型。

        List<String> name = new ArrayList<String>();         List<Integer> age = new ArrayList<Integer>();         List<Number> number = new ArrayList<Number>();         //getUperNumber(name);//1         getUperNumber(age);//2         getUperNumber(number);//3 public static void getData(List<?> data) {……}    public static void getUperNumber(List<? extends Number> data) {……}      

解析: 在(//1)处会出现错误,由于getUperNumber()方法中的参数已经限定了参数泛型上限为Number,因此泛型为String是不在这个范围以内,因此会报错

三、类型通配符下限经过形如 List<? super Number>来定义,表示类型只能接受Number及其三层父类类型,如Objec类型的实例。

 

Java 序列化

Java 提供了一种对象序列化的机制,该机制中,一个对象能够被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。

将序列化对象写入文件以后,能够从文件中读取出来,而且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型能够用来在内存中新建对象。

整个过程都是 Java 虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象能够在另外一个彻底不一样的平台上反序列化该对象。

类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。

ObjectOutputStream 类包含不少写方法来写各类数据类型,可是一个特别的方法例外:

public final void writeObject(Object x) throws IOException

上面的方法序列化一个对象,并将它发送到输出流。类似的 ObjectInputStream 类包含以下反序列化一个对象的方法:

public final Object readObject() throws IOException,                                   ClassNotFoundException

该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,所以,你须要将它转换成合适的数据类型。

请注意,一个类的对象要想序列化成功,必须知足两个条件:

  1. 该类必须实现 java.io.Serializable 对象。
  2. 该类的全部属性必须是可序列化的。若是有一个属性不是可序列化的,则该属性必须注明是短暂的。

若是你想知道一个 Java 标准类是不是可序列化的,请查看该类的文档。检验一个类的实例是否能序列化十分简单, 只须要查看该类有没有实现 java.io.Serializable接口。

 

序列化对象

ObjectOutputStream 类用来序列化一个对象,以下的 SerializeDemo 例子实例化了一个 Employee 对象,并将该对象序列化到一个文件中。

该程序执行后,就建立了一个名为 employee.ser 文件。该程序没有任何输出,可是你能够经过代码研读来理解程序的做用。

注意: 当序列化一个对象到文件时, 按照 Java 的标准约定是给文件一个 .ser 扩展名。

      Employee e = new Employee();       e.name = "Reyan Ali";       e.address = "Phokka Kuan, Ambehta Peer";       e.SSN = 11122333;       e.number = 101;       try       {          FileOutputStream fileOut =          new FileOutputStream("/tmp/employee.ser");          ObjectOutputStream out = new ObjectOutputStream(fileOut);          out.writeObject(e);          out.close();          fileOut.close();          System.out.printf("Serialized data is saved in /tmp/employee.ser");       }catch(IOException i)       {           i.printStackTrace();       }

 

反序列化对象

下面的 DeserializeDemo 程序实例了反序列化,/tmp/employee.ser 存储了 Employee 对象。

  Employee e = null;   try       {          FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");          ObjectInputStream in = new ObjectInputStream(fileIn);          e = (Employee) in.readObject();          in.close();          fileIn.close();       }catch(IOException i)       {          i.printStackTrace();          return;       }catch(ClassNotFoundException c)       {          System.out.println("Employee class not found");          c.printStackTrace();          return;       }

这里要注意如下要点:

readObject() 方法中的 try/catch代码块尝试捕获 ClassNotFoundException 异常。对于 JVM 能够反序列化对象,它必须是可以找到字节码的类。若是JVM在反序列化对象的过程当中找不到该类,则抛出一个 ClassNotFoundException 异常。

注意,readObject() 方法的返回值被转化成 Employee 引用。

当对象被序列化时,属性 SSN 的值为 111222333,可是由于该属性是短暂的,该值没有被发送到输出流。因此反序列化后 Employee 对象的 SSN 属性为 0。

 public transient int SSN;

 

Java 网络编程

java.net 包中提供了两种常见的网络协议的支持:

TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通讯。一般用于互联网协议,被称 TCP / IP。

UDP:UDP 是用户数据报协议的缩写,一个无链接的协议。提供了应用程序之间要发送的数据的数据包。

 

Socket 编程

套接字使用TCP提供了两台计算机之间的通讯机制。 客户端程序建立一个套接字,并尝试链接服务器的套接字。

当链接创建时,服务器会建立一个 Socket 对象。客户端和服务器如今能够经过对 Socket 对象的写入和读取来进行通讯。

java.net.Socket 类表明一个套接字,而且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们创建链接的机制。

如下步骤在两台计算机之间使用套接字创建TCP链接时会出现:

l  服务器实例化一个 ServerSocket 对象,表示经过服务器上的端口通讯。

l  服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端链接到服务器上给定的端口。

l  服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求链接。

l  Socket 类的构造函数试图将客户端链接到指定的服务器和端口号。若是通讯被创建,则在客户端建立一个 Socket 对象可以与服务器进行通讯。

l  在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 链接到客户端的 socket。

链接创建后,经过使用 I/O 流在进行通讯,每个socket都有一个输出流和一个输入流,客户端的输出流链接到服务器端的输入流,而客户端的输入流链接到服务器端的输出流。

TCP 是一个双向的通讯协议,所以数据能够经过两个数据流在同一时间发送.如下是一些类提供的一套完整的有用的方法来实现 socket。

 

ServerSocket 类的方法

服务器应用程序经过使用 java.net.ServerSocket 类以获取一个端口,而且侦听客户端请求。

建立非绑定服务器套接字。 若是 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,而且侦听客户端请求。

这里有一些 ServerSocket 类的经常使用方法:

序号

方法描述

1

public int getLocalPort()

  返回此套接字在其上侦听的端口。

2

public Socket accept() throws IOException

侦听并接受到此套接字的链接。

3

public void setSoTimeout(int timeout)

 经过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。

4

public void bind(SocketAddress host, int backlog)

将 ServerSocket 绑定到特定地址(IP 地址和端口号)。

 

Socket 类的方法

java.net.Socket 类表明客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象经过实例化 ,而 服务器得到一个 Socket 对象则经过 accept() 方法的返回值。

当 Socket 构造方法返回,并无简单的实例化了一个 Socket 对象,它实际上会尝试链接到指定的服务器和端口。

下面列出了一些感兴趣的方法,注意客户端和服务器端都有一个 Socket 对象,因此不管客户端仍是服务端都可以调用这些方法。

序号

方法描述

1

public void connect(SocketAddress host, int timeout) throws IOException

将此套接字链接到服务器,并指定一个超时值。

2

public InetAddress getInetAddress()

 返回套接字链接的地址。

3

public int getPort()

返回此套接字链接到的远程端口。

4

public int getLocalPort()

返回此套接字绑定到的本地端口。

5

public SocketAddress getRemoteSocketAddress()

返回此套接字链接的端点的地址,若是未链接则返回 null。

6

public InputStream getInputStream() throws IOException

返回此套接字的输入流。

7

public OutputStream getOutputStream() throws IOException

返回此套接字的输出流。

8

public void close() throws IOException

关闭此套接字。

 

InetAddress 类的方法

这个类表示互联网协议(IP)地址。下面列出了 Socket 编程时比较有用的方法:

序号

方法描述

1

static InetAddress getByAddress(byte[] addr)

在给定原始 IP 地址的状况下,返回 InetAddress 对象。

2

static InetAddress getByAddress(String host, byte[] addr)

根据提供的主机名和 IP 地址建立 InetAddress。

3

static InetAddress getByName(String host)

在给定主机名的状况下肯定主机的 IP 地址。

4

String getHostAddress() 

返回 IP 地址字符串(以文本表现形式)。

5

String getHostName() 

 获取此 IP 地址的主机名。

6

static InetAddress getLocalHost()

返回本地主机。

7

String toString()

将此 IP 地址转换为 String。

 

Java 发送邮件

 

Java 多线程编程

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中能够并发多个线程,每条线程并行执行不一样的任务。

多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。

这里定义和线程相关的另外一个术语 - 进程:一个进程包括由操做系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到全部的非守护线程都结束运行后才能结束。

多线程能知足程序员编写高效率的程序来达到充分利用 CPU 的目的。

 

一个线程的生命周期

 

新建状态:

使用 new 关键字和 Thread 类或其子类创建一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

就绪状态:

当线程对象调用了start()方法以后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度

运行状态:

若是就绪状态的线程获取 CPU 资源,就能够执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它能够变为阻塞状态、就绪状态和死亡状态。

阻塞状态:

若是一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源以后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或得到设备资源后能够从新进入就绪状态。能够分为三种:

n  等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

n  同步阻塞:线程在获取 synchronized 同步锁失败(由于同步锁被其余线程占用)。

n  其余阻塞:经过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程从新转入就绪状态。

死亡状态:

一个运行状态的线程完成任务或者其余终止条件发生时,该线程就切换到终止状态。

 

线程的优先级

每个 Java 线程都有一个优先级,这样有助于操做系统肯定线程的调度顺序。

Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。

默认状况下,每个线程都会分配一个优先级 NORM_PRIORITY(5)。

具备较高优先级的线程对程序更重要,而且应该在低优先级的线程以前分配处理器资源。可是,线程优先级不能保证线程执行的顺序,并且很是依赖于平台。

 

建立一个线程

Java 提供了三种建立线程的方法:

l  经过实现 Runnable 接口;

l  经过继承 Thread 类自己;

l  经过 Callable 和 Future 建立线程。

 

经过实现 Runnable 接口来建立线程

建立一个线程,最简单的方法是建立一个实现 Runnable 接口的类。

为了实现 Runnable,一个类只须要执行一个方法调用 run(),声明以下:

public void run()

能够重写该方法,重要的是理解的 run() 能够调用其余方法,使用其余类,并声明变量,就像主线程同样。

在建立一个实现 Runnable 接口的类以后,你能够在类中实例化一个线程对象。

Thread 定义了几个构造方法,下面的这个是咱们常用的:

Thread(Runnable threadOb,String threadName);

这里,threadOb 是一个实现 Runnable 接口的类的实例,而且 threadName 指定新线程的名字。

新线程建立以后,你调用它的 start() 方法它才会运行。

void start();

 

经过继承Thread来建立线程

建立一个线程的第二种方法是建立一个新的类,该类继承 Thread 类,而后建立一个该类的实例。

继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。

该方法尽管被列为一种多线程实现方式,可是本质上也是实现了 Runnable 接口的一个实例。

 

Thread 方法

下表列出了Thread类的一些重要方法:

序号

方法描述

1

public void start()

使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

2

public void run()

若是该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;不然,该方法不执行任何操做并返回。

3

public final void setName(String name)

改变线程名称,使之与参数 name 相同。

4

public final void setPriority(int priority)

 更改线程的优先级。

5

public final void setDaemon(boolean on)

将该线程标记为守护线程或用户线程。

6

public final void join(long millisec)

等待该线程终止的时间最长为 millis 毫秒。

7

public void interrupt()

中断线程。

8

public final boolean isAlive()

测试线程是否处于活动状态。

 

经过 Callable 和 Future 建立线程

l  1. 建立 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将做为线程执行体,而且有返回值。

l  2. 建立 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。

l  3. 使用 FutureTask 对象做为 Thread 对象的 target 建立并启动新线程。

l  4. 调用 FutureTask 对象的 get() 方法来得到子线程执行结束后的返回值。

 

建立线程的三种方式的对比

l  1. 采用实现 Runnable、Callable 接口的方式建立多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还能够继承其余类。

l  2. 使用继承 Thread 类的方式建立多线程时,编写简单,若是须要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 便可得到当前线程。

 

线程的几个主要概念

在多线程编程时,你须要了解如下几个概念:

l  线程同步

l  线程间通讯

l  线程死锁

l  线程控制:挂起、中止和恢复

 

多线程的使用

有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统须要并发执行,这时候就须要利用多线程编程。

经过对多线程的使用,能够编写出很是高效的程序。不过请注意,若是你建立太多的线程,程序执行的效率其实是下降了,而不是提高了。

请记住,上下文的切换开销也很重要,若是你建立了太多的线程,CPU 花费在上下文的切换的时间将多于执行程序的时间!

 

Java Applet 基础

Applet是采用Java编程语言编写的小应用程序,该程序能够包含在 HTML标准通用标记语言的一个应用)页中,与在页中包含图像的方式大体相同。含有Applet的网页的HTML文件代码中部带有<applet> 和</applet>这样一对标记,当支持Java的网络浏览器遇到这对标记时,就将下载相应的小应用程序代码并在本地计算机上执行该Applet。

Applet 是一种 Java 程序。它通常运行在支持 Java 的 Web 浏览器内。由于它有完整的 Java API支持,因此Applet 是一个全功能的 Java 应用程序。

以下所示是独立的 Java 应用程序和 applet 程序之间重要的不一样:

l  Java 中 Applet 类继承了 java.applet.Applet 类。

l  Applet 类没有定义 main(),因此一个 Applet 程序不会调用 main() 方法。

l  Applet 被设计为嵌入在一个 HTML 页面。

l  当用户浏览包含 Applet 的 HTML 页面,Applet 的代码就被下载到用户的机器上。

l  要查看一个 Applet 须要 JVM。 JVM 能够是 Web 浏览器的一个插件,或一个独立的运行时环境。

l  用户机器上的 JVM 建立一个 Applet 类的实例,并调用 Applet 生命周期过程当中的各类方法。

l  Applet 有 Web 浏览器强制执行的严格的安全规则,Applet 的安全机制被称为沙箱安全。

l  Applet 须要的其余类能够用 Java 归档(JAR)文件的形式下载下来。

 

Applet的生命周期

Applet 类中的四个方法给咱们提供了一个框架,你能够在该框架上开发小程序:

init: 该方法的目的是为你的 Applet 提供所需的任何初始化。在 Applet 标记内的 param 标签被处理后调用该方法。

start: 浏览器调用 init 方法后,该方法被自动调用。每当用户从其余页面返回到包含 Applet 的页面时,则调用该方法。

stop: 当用户从包含 Applet 的页面移除的时候,该方法自动被调用。所以,能够在相同的 Applet 中反复调用该方法。

destroy: 此方法仅当浏览器正常关闭时调用。由于 Applet 只有在 HTML 网页上有效,因此你不该该在用户离开包含 Applet 的页面后遗漏任何资源。

paint: 该方法在 start() 方法以后当即被调用,或者在 Applet 须要重绘在浏览器的时候调用。paint() 方法实际上继承于 java.awt。

 

Applet 的调用

Applet 是一种 Java 程序。它通常运行在支持 Java 的 Web 浏览器内。由于它有完整的 Java API 支持,因此 Applet 是一个全功能的 Java 应用程序。

<applet> 标签是在HTML文件中嵌入 Applet 的基础。如下是一个调用"Hello World"applet的例子;

<html><title>The Hello, World Applet</title><hr><applet code="HelloWorldApplet.class" width="320" height="120">If your browser was Java-enabled, a "Hello, World" message would appear here.</applet><hr></html>

 

Java 文档注释

Java 支持三种注释方式。前两种分别是 // 和 /* */第三种被称做说明注释,它以 /** 开始,以 */结束。

说明注释容许你在程序中嵌入关于程序的信息。你可使用 javadoc 工具软件来生成信息,并输出到HTML文件中。

说明注释,使你更加方便的记录你的程序信息。

 

javadoc 标签

javadoc 工具软件识别如下标签:

标签

描述

示例

@author

标识一个类的做者

@author description

@deprecated

指名一个过时的类或成员

@deprecated description

 

@param

说明一个方法的参数

@param parameter-name explanation

@return

说明返回值类型

@return explanation

 

@version

指定类的版本

@version info

 

文档注释

在开始的 /** 以后,第一行或几行是关于类、变量和方法的主要描述。

以后,你能够包含一个或多个何种各样的 @ 标签。每个 @ 标签必须在一个新行的开始或者在一行的开始紧跟星号(*).

多个相同类型的标签应该放成一组。例如,若是你有三个 @see 标签,能够将它们一个接一个的放在一块儿。

下面是一个类的说明注释的实例:

/*** 这个类绘制一个条形图 * @author runoob * @version 1.2 */

 

javadoc 输出什么

javadoc 工具将你 Java 程序的源代码做为输入,输出一些包含你程序注释的HTML文件。

每个类的信息将在独自的HTML文件里。javadoc 也能够输出继承的树形结构和索引。

因为 javadoc 的实现不一样,工做也可能不一样,你须要检查你的 Java 开发系统的版本等细节,选择合适的 Javadoc 版本。

实例

下面是一个使用说明注释的简单实例。注意每个注释都在它描述的项目的前面。

在通过 javadoc 处理以后,SquareNum 类的注释将在 SquareNum.html 中找到。

import java.io.*;/** * 这个类演示了文档注释 * @author Ayan Amhed * @version 1.2 */public class SquareNum {    /**    * This method returns the square of num.    * This is a multiline description. You can use    * as many lines as you like.    * @param num The value to be squared.    * @return num squared.    */    public double square(double num) {       return num * num;    }    /**    * This method inputs a number from the user.    * @return The value input as a double.    * @exception IOException On input error.    * @see IOException    */    public double getNumber() throws IOException {       InputStreamReader isr = new InputStreamReader(System.in);       BufferedReader inData = new BufferedReader(isr);       String str;       str = inData.readLine();       return (new Double(str)).doubleValue();    }    /**    * This method demonstrates square().    * @param args Unused.    * @return Nothing.    * @exception IOException On input error.    * @see IOException    */    public static void main(String args[]) throws IOException    {       SquareNum ob = new SquareNum();       double val;       System.out.println("Enter value to be squared: ");       val = ob.getNumber();       val = ob.square(val);       System.out.println("Squared value is " + val);    }}

 

Java 实例

http://www.runoob.com/java/java-examples.html

 

Java 8 新特性

http://www.runoob.com/java/java8-new-features.html

Java8 新增了很是多的特性,咱们主要讨论如下几个:

Lambda 表达式 − Lambda容许把函数做为一个方法的参数(函数做为参数传递进方法中。

方法引用 − 方法引用提供了很是有用的语法,能够直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可使语言的构造更紧凑简洁,减小冗余代码。

默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。

新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。

Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。

Date Time API − 增强对日期与时间的处理。

Optional  − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。

Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它容许咱们在JVM上运行特定的javascript应用。

更多的新特性能够参阅官网:What's New in JDK 8

 

Java MySQL 链接

建立测试数据

CREATE TABLE `websites` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `name` char(20) NOT NULL DEFAULT '' COMMENT '站点名称',   `url` varchar(255) NOT NULL DEFAULT '',   `alexa` int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名',   `country` char(10) NOT NULL DEFAULT '' COMMENT '国家',   PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

链接数据库

Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dalong?Unicode=true&characterEncoding=UTF-8",        "root", "admin");

 

Java 9 新特性

http://www.runoob.com/java/java9-new-features.html

模块系统:模块是一个包的容器,Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)。

REPL (JShell):交互式编程环境。

HTTP 2 客户端:HTTP/2标准是HTTP协议的最新版本,新的 HTTPClient API 支持 WebSocket 和 HTTP2 流以及服务器推送特性。

改进的 Javadoc:Javadoc 如今支持在 API 文档中的进行搜索。另外,Javadoc 的输出如今符合兼容 HTML5 标准。

多版本兼容 JAR 包:多版本兼容 JAR 功能能让你建立仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本。

集合工厂方法:List,Set 和 Map 接口中,新的静态工厂方法能够建立这些集合的不可变实例。

私有接口方法:在接口中使用private私有方法。咱们可使用 private 访问修饰符在接口中编写私有方法。

进程 API: 改进的 API 来控制和管理操做系统进程。引进 java.lang.ProcessHandle 及其嵌套接口 Info 来让开发者逃离时常由于要获取一个本地进程的 PID 而不得不使用本地代码的窘境。

改进的 Stream API:改进的 Stream API 添加了一些便利的方法,使流处理更容易,并使用收集器编写复杂的查询。

改进 try-with-resources:若是你已经有一个资源是 final 或等效于 final 变量,您能够在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。

改进的弃用注解 @Deprecated:注解 @Deprecated 能够标记 Java API 状态,能够表示被标记的 API 将会被移除,或者已经破坏。

改进钻石操做符(Diamond Operator) :匿名类可使用钻石操做符(Diamond Operator)。

改进 Optional 类:java.util.Optional 添加了不少新的有用方法,Optional 能够直接转为 stream。

多分辨率图像 API:定义多分辨率图像API,开发者能够很容易的操做和展现不一样分辨率的图像了。

改进的 CompletableFuture API : CompletableFuture 类的异步机制能够在 ProcessHandle.onExit 方法退出时执行操做。

轻量级的 JSON API:内置了一个轻量级的JSON API

响应式流(Reactive Streams) API: Java 9中引入了新的响应式流 API 来支持 Java 9 中的响应式编程。

更多的新特性能够参阅官网:What's New in JDK 9

相关文章
相关标签/搜索