from:自强学堂
Java简介
Java是面向对象程序设计和Java平台的总称。
Java EE Java平台标准版
Java SE Java平台企业版
Java ME Java平台微型版
特性
- 简单
语法类似C语言和C++语言,没有操作符重载,多继承,自动的强制类型转换;不使用指针而使用引用,有自动的废料收集。 - 面向对象的
提供类、继承和接口等原语。只支持类之间的单继承,接口之间的多继承,支持类与接口之间的实现机制(implements)。Java全面支持动态绑定。 - 分布的
支持Internet的开发,在基本的Java应用编程接口中有一个网络应用编程接口(Java net),提供网络应用编程的类库,包括URL、URLConnection、Socket、ServerSockt等。Java的RMI(远程激活方法)机制是开发分布式的重要手段。 - 健壮的
- 安全的
Java通常被用在网络环境中,为此Java提供一个安全机制以防恶意代码的攻击。Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查、并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。 - 体系结构中立的
Java程序在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后在实现这个Java平台的任何系统中运行。 - 可移植的
Java编译器使用Java实现的,Java的运行环境是用ANSI C实现的 - 解释型的
在运行时,Java平台中的Java解释器对这些字节码进行解释,执行过程中需要的类在连接阶段被载入到运行环境中 - 高性能
- 多线程
在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable)的构造子将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
- 动态的
Java程序需要的类能够动态的被载入到运行环境,也可以通过网络来载入所需要的类。Java中的类有一个运行时刻的标志,能进行运行时刻的类型检查。
Java基础语法
- 对象
- 类
- 方法
【注意】
- 大小写敏感
- 类名:对于所有类来说类名的首字母应该大写。若类名由若干个单词组成,每个单词的首字母应该大写。
- 方法名:所有的方法名应该以小写字母开头。若方法名含有若干个单词,则后面的每个单词首字母大写
- 源文件名:源文件名必须和类名相同。
- 主方法入口:所有的Java程序由public static void main(String args[ ])方法开始执行。
- Java标识符
+ 所有标识符都应该以字母(a-z/A-Z),美元符 $ 或者下划线开始
+ 首字母之后可以是任意字符
+ 不可以用关键字
+ 标识符大小写敏感 - 修饰符
+ 可访问修饰符:default, public, protected, private
+ 不可访问修饰符:final, abstract, strictfp(浮点数比较使用严格的规则)
Java关键字
关键字 | 描述 |
---|---|
abstract | 抽象方法,抽象类的修饰符 |
assert | 断言条件是否满足 |
boolean | 布尔数据类型 |
break | 跳出循环或者label代码段 |
byte | 8-bit有符号数据类型 |
case | switch语句的一个条件 |
catch | 和try搭配捕捉异常信息 |
char | 16-bit unicode字符数据类型 |
class | 定义类 |
const | 未使用 |
continue | 不执行循环体剩余部分 |
default | switch语句中的默认分支 |
do | 循环语句,循环体至少会执行一次 |
double | 64-bit双精度浮点数 |
else | if条件不成立时执行的分支 |
enum | 枚举类型 |
extends | 表示一个类是另一个类的子类 |
final | 表示一个值在初始化之后就不能再改变了,表示方法不能被重写,或者一个类不能有子类 |
finally | 为了完成执行的代码而设计的,主要是为了程序的健壮性和完整性,无论有没有异常发生都执行。 |
float | 32-bit单精度浮点数 |
for | for循环语句 |
goto | 未使用 |
if | 条件语句 |
implements | 表示一个类实现了接口 |
import | 导入类 |
instanceof | 测试一个对象是否是某个类的实例 |
int | 32位整型数 |
interface | 接口,一种抽象的类型,仅有方法和常量的定义 |
long | 64位整型数据 |
native | 表示方法用非Java代码实现 |
new | 分配新的类实例 |
package | 一系列相关类组成一个包 |
protected | 标识字段只能通过类或者其子类访问子类或者在同一个包内的其他类 |
public | 表示共有属性或方法 |
return | 返回方法 |
short | 16位数字 |
static | 表示在类级别定义,所有实例共享的 |
strictfp | 浮点数比较使用的严格的规则 |
super | 表示基类 |
switch | 选择语句 |
synchronized | 表示同一时间只能由一个线程访问的代码块 |
this | 表示调用当前实例或者调用另一个构造函数 |
throw | 抛出异常 |
throws | 定义方法可能抛出的异常 |
transient | 修饰不要序列化的字段 |
try | 表示代码块要做异常处理或者和finally配合表示是否抛出异常都执行finally中的代码 |
void | 标记方法不返回任何值 |
volatile | 标记字段可能会被多个线程同时访问,而不做同步 |
while | while循环 |
源文件声明规则
当在一个源文件中定义多个类,并且还有import和package语句时,要注意:
- 一个源文件中只能有一个public类
- 一个源文件可以有多个非public类
- 如果一个类定义在某个包中,那么package语句应该在源文件的首行
- 如果有import语句,应该放在package语句和类定义之间,如果没有package语句,则应该放句首。
- 。。。
数据类型
内置数据类型
byte:
8位,有符号的,以二进制补码表示的整数
范围-128~127
默认值0
byte类型用在大型数组中节省空间,主要代替整数,因为byte变量占用的空间只有int类型的1/4
short:
16位,有符号,二进制补码表示
范围-32768~32767
一个short变量是int型变量所占空间的1/2
int:
32位,有符号,二进制补码
-2,147,483,648~2,147,485,647(231)
默认值是0
long:
64位有符号,二进制补码表示
-263 ~ 263-1
默认值是0L
float:
单精度,32位,IEEE754标准的浮点数
默认值0.0f
浮点数不能用来表示精确的值如货币
double:
双精度,64位,IEEE754标准
浮点数默认为double类型
默认值0.0f
boolean:
true和false
默认值是false
char:
单一的15位unicode字符
最小值为’\u0000’(即为0)最大值’\ffff’(即为65535)
引用类型
- 引用类型变量由类的构造函数创建
- 对象,数组都是引用数据类型
- 所有i你用的默认值是null
- 一个引用变量可以用来引用任何兼容的类型
Java常量
final标志
final double PI=3.1415927
- 为了便于识别,通常使用大写字母表示常量
- 前缀o表示八进制,前缀0x表示十六进制
- 字符串常量包含在两个引号之间
Java变量类型
变量在使用之前必须声明,像c++
- 局部变量
- 成员变量
- 类变量(静态变量)
- 局部变量没有默认值,被声明后必须经过初始化才可以使用
- 实例变量具有默认值,数值型默认值为0,布尔型变量默认值false,引用类型变量默认值是null
Java修饰符
访问控制修饰符
- default 默认的,同一包内可见
当不使用任何关键字的时候,默认接口里的变量隐式声明为public static final;接口里的方法默认public - private 私有的,在同一类内可见
变量和构造方法只能被所属类访问,并且类和接口不能声明为private - public 共有的,对所有类可见
- protected 受保护的,对同一包内的类和所有子类可见
访问控制和继承
- 父类中声明为public的方法在子类中也必须为public
- 父类中为protected的方法在子类中要么声明为protected,要么声明为public
- 父类中默认修饰符声明的方法,能够在子类中声明为private
- 父类中声明为private的方法不能够被继承
非访问修饰符
Static 修饰符
- 静态变量:
static关键字用来声明独立于对象的静态变量,==无论一个类实例化多少对象,他的静态变量只有一份拷贝。==静态变量也被称为类变量。局部变量只能被声明为static变量。 - 静态方法:
static关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
Final修饰符
- Final变量
被声明为final的对象的引用不能指向不同的对象。但final对象里的数据可以被改变。也就是说final对象的引用不能改变,但是里面的值可以改变
Final修饰符通常和static修饰符一起使用来创建类常量
public class Test{
final int value = 10;
// 下面是声明常量的实例
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue(){
value = 12; //将输出一个错误
}
}
???按照上述说法,不可以修改value的引用,但可以修改value的值。。。。。那个是引用嘞?value=12不是修改的值么???
-
Final方法
Final方法可以被子类继承,但是不能被子类修改。
声明final方法的最主要目的是防止该方法的内容被修改。 -
Final类
Final类可以被继承,没有类能够继承final类的任何特性
public final class Test{
//类体
}
Abstract修饰符
抽象类:
抽象类不能用来实例化对象,生命抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被声明为abstrac和final。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则编译器报错。
抽象方法:
抽象方法是一种没有任何实现的方法,该方法的实现交给其子类提供。抽象方法不能被声明成final和strict
任何抽象类的子类必须实现父亲的所有抽象方法,除非该子类也是抽象类。
含有抽象方法的必定声明为抽象类,抽象类不一定包含抽象方法。
Synchronized修饰符
Synchronized关键字声明的方法同一时间只能被一个线程访问
…
Transient修饰符
序列化的对象包含被transient修饰的实例变量时,JVM跳过该特定的变量
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
volatile修饰符
volatile修饰的成员变量在每次线程被访问的时候,都强迫从共享内存中重读该成员变量的值。而且,当该成员变量发生变化的时候,强迫线程将变化值写到共享内存。这样在任何时刻两个不同的线程总是看到某个成员变量的同一个值。一个volatile对象引用可能是null
Java算数运算符
位运算符
-
^ 异或
-
按位补运算符反转操作数的每一位
>>> 按位右移补零
instanceOf运算符
用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)
( Object reference variable ) instanceOf (class/interface type)
如果左侧变量所指的对象是或兼容于右侧类或接口的一个对象,那么结果为真。
class Vehicle{}
public class Car extends Vechile{
public static void main(String args[]){
Vehile a = new Car();
boolean result = a instanceof Car;
System.out.println(result);
}
}
true
循环
Java增强for循环
【p.s.感觉很像python的for循环】
Java5引入一种主要用于数组的增强型for循环
for(声明语句:表达式)
{
//代码
}
**声明语句:**声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值于此时数组元素的值相等
**表达式:**表达式是要访问的数组名,或者是返回值为数组的方法
public class Test {
public static void main(String args[]){
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
System.out.print(",");
}
System.out.print("\n");
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
}
}
}
以上实例编译运行结果如下:
10,20,30,40,50,
James,Larry,Tom,Lacy,
分支结构
switch…case
- switch语句中的变量类型只能为byte、short、int或者char。
- switch语句可以包含一个default分支,该分支必须是switch语句的最后一个分支。default在没有case语句的值和变量值相等的时候执行。default分支不需要break语句。
Number类
Java为每一个内置数据类型提供了对应的包装类。所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类Number的子类。
Number类的成员方法
序号 | 方法与描述 |
---|---|
1 | xxxValue() 将number对象转换为xxx数据类型的值并返回。 |
2 | compareTo() 将number对象与参数比较。 |
3 | equals() 判断number对象是否与参数相等。 |
4 | valueOf() 返回一个Integer对象指定的内置数据类型 |
5 | toString() 以字符串形式返回值。 |
6 | parseInt() 将字符串解析为int类型。 |
7 | abs() 返回参数的绝对值。 |
8 | ceil() 对整形变量向左取整,返回类型为double型。 |
9 | floor() 对整型变量向右取整。返回类型为double类型。 |
10 | rint() 返回与参数最接近的整数。返回类型为double。 |
11 | round() 返回一个最接近的int、long型值。 |
12 | min() 返回两个参数中的最小值。 |
13 | max() 返回两个参数中的最大值。 |
14 | exp() 返回自然数底数e的参数次方。 |
15 | log() 返回参数的自然数底数的对数值。 |
16 | pow() 返回第一个参数的第二个参数次方。 |
17 | sqrt() 求参数的算术平方根。 |
18 | sin() 求指定double类型参数的正弦值。 |
19 | cos() 求指定double类型参数的余弦值。 |
20 | tan() 求指定double类型参数的正切值。 |
21 | asin() 求指定double类型参数的反正弦值。 |
22 | acos() 求指定double类型参数的反余弦值。 |
23 | atan() 求指定double类型参数的反正切值。 |
24 | atan2() 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值。 |
25 | toDegrees() 将参数转化为角度。 |
26 | toRadians() 将角度转换为弧度。 |
27 | random() 返回一个随机数。 |
Character类
在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情况。为了解决这个问题,Java语言为内置数据类型char提供了包装类Character类。
Character类提供了一系列方法来操纵字符。你可以使用Character的构造方法创建一个Character类对象,例如:
Character ch = new Character(‘a’);
在某些情况下,Java编译器会自动创建一个Character对象。
例如,将一个char类型的参数传递给需要一个Character类型参数的方法时,那么编译器会自动地将char类型参数转换为Character对象。 这种特征称为装箱,反过来称为拆箱。
Character方法
序号 | 方法与描述 |
---|---|
1 | isLetter() 是否是一个字母 |
2 | isDigit() 是否是一个数字字符 |
3 | isWhitespace() 是否一个空格 |
4 | isUpperCase() 是否是大写字母 |
5 | isLowerCase() 是否是小写字母 |
6 | toUpperCase() 指定字母的大写形式 |
7 | toLowerCase() 指定字母的小写形式 |
8 | toString() 返回字符的字符串形式,字符串的长度仅为1 |
Java String类
注意: String类是不可改变的,所以你一旦创建了String对象,那它的值就无法改变了。 如果需要对字符串做很多修改,那么应该选择使用==StringBuffer & StringBuilder ==类。
当对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类。
和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder类在Java 5中被提出,它和StringBuffer之间的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问)。
由于StringBuilder相较于StringBuffer有速度优势,所以多数情况下建议使用StringBuilder类。然而在应用程序要求线程安全的情况下,则必须使用StringBuffer类。
Java数组
声明数组变量
double[] myList; // 首选的方法
或
double myList[]; // 效果相同,但不是首选方法
创建数组
arrayRefVar = new dataType[srraySize];//1.使用dataType[arraySize]创建数组。2.将新创建的数组的引用赋值给变量arrayRefVar。
处理数组
数组的元素类型和数组的大小都是确定的,所以当处理书数组元素的时候,通常使用基本循环或者foreach循环
foreach循环
JDK1.5引进了一种新型的循环,被称为foreach循环或者加强型循环,它能在不适用下标的情况下遍历数组。
public class TestArray {
public static void main(String[] args) {
double[] myList = {1.9, 2.9, 3.4, 3.5};
// 打印所有数组元素
for (double element: myList) {
System.out.println(element);
}
}
}
以上实例编译运行结果如下:
1.9
2.9
3.4
3.5
数组作为函数的参数
public static void printArray(int[] array){
for (int i=0;i<array.length;i++ ){
System.out.print(array[i]+" ");
}
}
```
调用:
```java
printArray(new int[]{3,1,2,6,4,2});
Java正则表达式
Java继承
- 类的继承是单一继承,一个子类只能拥有一个父类。
- 关键字:extends 和 implements
- 所有的Java的类均是由java.lang.object类继承而来的,所以object是所有类的祖先,而除了object外,所有类必须有一个父类。
extends:子类可以继承父类的所有非private属性。
implement:在类继承接口的情况下使用。
IS-A关系
一个对象是另一个对象的分类。
HAS-A关系
代表类和它的成员之间的从属关系。有助于减少代码重用。
Java支支持单继承(继承基本类和抽象类),接口可以用来实现多继承,脚本结构如下:
public class Apple extends Fruit implements Fruit1,Fruit2{}
Java重写(override)与重载(overload)
重写的规则
外壳一样,修改内容
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更高。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 如果一个方法不能被继承,那么该方法不能被重写。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
Super关键字的使用
当需要在子类中调用父类的被重写的方法时,要使用super关键字。
class Animal{
public void move(){
System.out.println("动物可以移动“);
}
}
class Dog extends Animal{
public void move(){
super.move();
System.out.println("狗可以跑和走”);
}
}
public class TestDog{
public static void main(String args[]){
Animal b= new Dog();
b.move();
}
}
运行结果:
动物可以移动
狗可以跑和走
重载规则
名字一样,参数表不一样
- 被重载的方法必须改变参数列表;
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
Java多态
在Java中所有的对象都具有多态性,因为任何对象都能通过IS-A测试的类型和Object类
访问一个对象的唯一的方法就是通过引用型变量。
public class Employee
{
private String name;
private String address;
private int number;
public Employee(String name, String address, int number)
{
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck()
{
System.out.println("Mailing a check to " + this.name
+ " " + this.address);
}
public String toString()
{
return name + " " + address + " " + number;
}
public String getName()
{
return name;
}
public String getAddress()
{
return address;
}
public void setAddress(String newAddress)
{
address = newAddress;
}
public int getNumber()
{
return number;
}
}
public class Salary extends Employee
{
private double salary; //Annual salary
public Salary(String name, String address, int number, double
salary)
{
super(name, address, number);//调用父类的(employee)
setSalary(salary);
}
public void mailCheck()
{
System.out.println("Within mailCheck of Salary class ");
System.out.println("Mailing check to " + getName()
+ " with salary " + salary);
}
public double getSalary()
{
return salary;
}
public void setSalary(double newSalary)
{
if(newSalary >= 0.0)
{
salary = newSalary;
}
}
public double computePay()
{
System.out.println("Computing salary pay for " + getName());
return salary/52;
}
}
public class VirtualDemo
{
public static void main(String [] args)
{
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Call mailCheck using Salary reference --");
s.mailCheck();
System.out.println("\n Call mailCheck using Employee reference--");
e.mailCheck();
}
}
输出结果:
Constructing an Employee //salary s
Constructing an Employee //employee e
Call mailCheck using Salary reference –
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3,3600.00
Call mailCheck using Employee reference–
Mailing a check to John Adams Boston, MA
Mailing check to John Adams with salary 2400.0
因为e是Employee的引用,所以调用e的mailCheck()方法则有完全不同的结果。
当编译器检查e.mailCheck()方法时,编译器检查到Employee类中的mailCheck()方法。
在编译的时候,编译器使用Employee类中的mailCheck()方法验证该语句,但是在运行的时候,Java虚拟机(JVM)调用的是Salary类中的mailCheck()方法。
该行为被称为虚拟方法调用,该方法被称为虚拟方法。
Java抽象类
abstract class:
抽象类除了不能实例化对象以外类的其他功能依旧建在。成员变量、成员方法、和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承才能被使用。因此,通常在设计阶段决定要不要设计抽抽象类。
继承抽象类:
通过一般的方法继承抽象类:extends
Java接口
接口Interface,在Java语言中是一个抽象类型,是抽象方法的集合。一个类通过继承接口的方式从而继承接口的抽象方法。
接口 不是 类。
接口包含类要实现的方法。除非实现接口的类是抽象类。否则该类要定义接口中的所有的方法。
接口无法被实例化,但可以被实现。一个实现接口的类,必须实现接口内所描述的所有的方法,否则就必须声明为抽象类。
接口类型可以用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个一次接口实现的对象。
接口与类的区别:
- 接口不能用于实例化对象
- 接口没有构造方法
- 接口中所有的方法必须是抽象方法
- 接口不能包含成员变量,除static和final变量
- 接口不是被类继承了而是要被类实现
- 接口支持多重继承---------(实现?)
接口的声明
[可见度】 interface 接口名称 [extends 其他的类名]{
//声明变量
//抽象方法
}
- 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字
- 接口中每一个方法也是隐式抽象的,声明时不需要关键字abstract
- 接口中的方法都是共有的
interface Animal{
public void eat();
public void travel();
}
接口的实现
当类实现接口的时候,类要实现接口中所有的方法。否则,类必须声明为抽象的类
类使用implements关键字实现接口。再类声明中,implements关键字放在class证明后面
interface Animal{
public void eat();
public void travel();
}
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
规则:
- 一个类可以同时实现多个接口
- 一个类只能继承一个类,但可以实现多个接口。
- 一个接口能继承另一个接口,与类之间的继承比较相似
接口的继承
一个接口能继承另一个接口,接口的继承使用ecxtends关键字,子接口继承父接口的方法。
public interface Sports
{
public void setHomeTeam(String name);
public void setVisitingTeam(String name);
}
// 文件名: Football.java
public interface Football extends Sports
{
public void homeTeamScored(int points);
public void visitingTeamScored(int points);
public void endOfQuarter(int quarter);
}
// 文件名: Hockey.java
public interface Hockey extends Sports
{
public void homeGoalScored();
public void visitingGoalScored();
public void endOfPeriod(int period);
public void overtimePeriod(int ot);
}
接口的多重继承
接口允许多重继承!!
public interface Hockey extends Sports, Event
标记接口
package java.util;
public interface EvenListener{}
没有任何方法的接口被称为标记接口。标记接口主要应用于以下两种目的:
-
建立一个公共的父接口:
-
向一个类添加数据类型:
Java数据结构
- 枚举(Enumeration)
- 位集合(BitSet)
- 向量(Vector)
- 栈
- 字典
- 哈希表
- 属性
- 集合框架(Collection)