Java
两种核心机制
:java
虚拟机
垃圾收集机制
源程序
(*.java)---java
编译器
---
字节码
(*.class)—
操作系统平台
Java
虚拟机可以理解成一个字节码为机器指令的
cpu
对于不同的运行平台
,
有不同的虚拟机
Java
虚拟机制屏蔽了底层运行平台的差别
,
实现了
”
一次编译
,
随处运行
”
Java
是解释型语言
J2SDK(
软件开发包
) JRE(java
运行环境
)
开发需要
JDK
用户需要
JRE
Bin
二进制
Dos
中输入
java –version
现在用的
jdk
版本
Path:window
系统执行命令时要搜寻的路径
Classpath:java
在编译和运行时要找的
class
所在的路径
1.Helloworld.java
Public class HelloWorld{
Public static void main(String[] args){
System.out.println(“HelloWorld”);
}
}
d:
cd java//
切换到
java
目录
javac HelloWorld.java
java HelloWorld
详细信息
工具
文件夹
应用到所有文件夹
显示所有文件和文件夹
不隐藏已知文件类型拓展名
在地址栏显示完整路径
类体
方法体
一个原文件中最多有一个
public
类
每个类对应一个
class
源文件的名必须和
public
类名相同
Java
语言注释三种注释方式
:
//
/* */
/**
*
*/
Java.lang.NoclassDefound
IDE
集成开发环境
J2se
基础语法
标识符
:
凡是自己可以起名字的
由字母
下划线
美元符
或数字组成
应以字母
,
数字
,
美元符
见名知意
关键字
:
专门用途
,
小写英文
Java
常量
:
用字符串表示
,
区分为不同的类型
Eg
整型常量
123
实型常量
3.14
字符常量
’a’
逻辑常量
true false
字符串常量
”helloworld”
“
常量
”
这个名词还会用在另外其它语境中表示值不可变的变量参见
Final
关键字
Java
变量
是程序中最基本的存储单元
,
其要素包括变量名
,
变量类型和作用域
Java
程序中每一个变量都属于特定的数据类型
,
在使用前必须对其声明
.
从本质上讲
,
变量其实是内存中的一小块区域
,
使用变量名来访问这块区域
,
因此
,
每一个变量使用前必须要先申请
(
声明),
然后必须进行赋值(
填充内容),
才能使用
.
程序执行过程
load
到内存
找到
main
方法开始执行
执行过程管理
:code segment
存放代码 data segment
静态变量字符串常量
Stack
局部变量 heap new
出来的东西(
内存分的四部分)
Java
变量的分类
按被声明的位置划分:
局部变量
:
方法或语句块内部定义的变量
(
包含方法参数
)
成员变量
:
方法外部
,
类的内部定义的变量
类外面不能有变量的声明
大括号里声明的变量
,
出了大括号就没人认识大括号里声明的变量
按所属的数据类型划分:
基本数据类型变量
4
类
8
种
逻辑型
boolen true false
不可以以
0
或非
0
的整数替代
文本型
字符型
char \u
后边的数是十六进制的编码
\n
换行符
\r
回车符
整数型
byte1 short1 int4 long8
八进制
0
开头
十六进制
0x
或
0X
开头整形默认为
int
型
,
声明
long
型常量可以后加
l
或
L
浮点数型
两种表示形式
十进制
科学记数
Float4 double8
默认
double
声明
float
型常量可以后加
f
或
F
引用数据类型变量
基本数据类型转换
:boolean
不可以转换为其他数据类型
整形
,
字符型
,
浮点型在混合运算中相互转换
Infinity
无小的转换成大的自动转化
大的转换成小的强制转换
Byte short char
转换成
int
处理
程序应该主义的问题
1.
大括号对其
2.
遇到
{
缩进
,Tab/shift+Tab
3.
程序块之间加空格
4.
并排语句之间加空格
5.
运算符两侧加空格
6.
{
前面有空格
7.
成对编程
运算符
算术运算符
逻辑运算符
赋值运算符
字符串连接符
“+”
运算符两侧的操作数中只要有一个是字符串类型,
系统会自动将另一个操作数转换为字符串然后在进行连接
当进行打印的时候,
无论任何类型都自动转换为字符串进行打印
Print
不换行
println
换行
表达式
表达式的类型和值
表达式的运算顺序
三目条件运算符
x?y:z x
为
boolean
类型
为
true
结果为
y
否则为
z
语句
条件语句
If
If..else..
If..else if..else..
For
循环语句
1+3+5+…+99
public class OddSum{
Public static void main(String[] args){
long result = 0;
for(int i=1; i<=99; i+=2){
result +=i;
}
System.out.println(“result=”+restult);
}
}
Int result=0;
For(int i=1;i<=99;i+=2)
{result+=i}
Tab shift+tab
While do while
Break continue
1 100
内前5
个可以被3
整除的数
输出101 200
内的质数
应该由哪些类对象
应该具有的属性方法
类和类之间的关系
Static
关键字
用
static
声明的成员变量为静态成员变量
,
它为该类的公用变量
,
在第一次使用时被初始化
,
对于该类的所有对象来说
,static
成员变量只有一份
.
可以通过对象引用或类名
(
不需要实例化
)
访问静态成员
用
static
声明的方法为静态方法
,
在调用该方法时
,
不会将对象的引用传递给它
,
所以在
static
方法中不可访问非
static
的成员
.
静态方法不再是针对于某个对象调用
,
所以不能访问非静态成员
Package
和import
语句
class
文件的最上层包的父目录位于
classpath
下
执行一个类需要写全包名
J2SDK
Java.lang
包含一些
java
语言的核心类
,
如
string,math,integer,system
和
thread,
提供常用功能
Java.awt
包含了构成抽象窗口工具集的多个类
,
这些类被用来构建和管理应用程序的图形用户界面
(GUI)
Java.applet
包含
applet
运行所需的一些类
Java.net
包含执行与网络相关的操作的类
Java.io
包含能提供多种输入
/
输出功能的类
Java.util
包含一些实用工具类
,
如定义系统特性
,
使用与日期日历相关的函数
Java.lang
不需引入
Dos
中打
jar
包的命令
jar –cvf xx.jar *.*
继承和权限控制
Extends
通过继承
,
子类自动拥有了基类的所有成员
(
成员变量和方法
)
Java
只支持单继承
,
不允许多继承
.
一个子类只能有一个基类
一个基类可以派生多个子类
Private
类内部
Default
类内部
同一个包
Protected
类内部
同一个包
子类
Public
类内部
同一个包
子类
任何地方
方法的重写
在子类中可以根据需要从基类中继承来的方法进行重写
重写方法和被重写方法具有相同方法名称
,
参数列表和返回类型
重写方法不能使用比被重写方法更严格的访问权限
Super
关键字
在
java
类中使用
super
来引用基类的成分
,eg
引用方法
继承中的构造方法
子类的构造过程中必须调用其基类的构造方法
子类可以在自己的构造方法中使用
super
调用基类的构造方法
使用
this
调用本类的另外的构造方法
如果调用
super,
必须写在子类构造方法的第一行
如果子类的构造方法中没有显示的调用基类构造方法
,
则系统默认调用基类无参数的构造方法
如果子类构造方法中既没有显式调用基类构造方法
,
而基类中又没有无参的构造方法
,
则编译出错
.
Object
类
Object
类是所有
java
类的根基类
Clone()
equals(Object obj)
finalize()
getClass()
拿到编译好的
class
文件
hashCode()
notify()
toString()
返回代表这个对象的字符串
toString
方法
object
类中定义有
public String toString()
方法
,
其返回值是
String
类型
,
描述当前对象的有关信息
.
在进行
String
与其它类型数据的连接操作是
(
如
:System.out.println)(“info”+person),
将自动调用该对象类的
toString()
方法
.
可以根据需要在用户自定义类型中重写
toString()
方法
.
Public class TestToString{
Public static void main(String[] args){
Dog d = new Dog();
System.out.println(“d:=”+d.toString); //object
类默认是哈希编码
}
}
Class Dog{
Public String toString(){
Return “I’m a cool Dog!”
}
}
哈希编码
:
独一无二的代表一个对象
.
并且通过哈希编码可以独一无二的找到这个对象的位置
.
在
java
虚拟机运行时需找到运行对象的地址
,
会用一张表记录每一个对象的位置
,
根据编码可以找到对象
.
equals()
方法
重写Public boolean equals(Object obj){}
public class TestEquals{
public static void main(String[] args){
Cat c1 = new Cat(1,2,3);
Cat c2 = new Cat(1,2,6);
System.out.println(c1 = c2); //
比较的是引用中的内容
,
不可能相同
System.out.println(c1.equals(c2));
//
上为
object
类
//
下为
string
类
string
类中的
equals
方法
序列一样就相等
String s1 = new String(“hello”);
String s2 = new String(“hello”);
System.out.println(s1 ==s2);
System.out.println(s1.equals(s2));
}
}
Class Cat{
Int color;
Int height,weight;
public Cat(int color,int height,int weight){
this.color = color;
this.height = height;
this.weight = weight;
}
Public boolean equals(Object obj){
if(obj = = null) return false;
else{
if(obj instanceof Cat){
Cat c = (Cat) obj;
If(c.color==this.color&&c.height==this.height&&c.weight ==this.weiget)
Return true;
}
}
}
Return false;
}
Object
的
equals
方法定义为
:x.equals(y)
当
x
和
y
是同一个对象的应用是返回
true
否则返回
false.
对象转型(casting)
一个基类的引用类型变量可以
”
指向
”
其子类的对象
.
一个基类的引用不可以访问其子类对象新增加的成员
(
属性和方法
)
可以使用引用变量
instanceof
类名
来判断该引用型变量所指向的对象是否属于该类或该类的子类
子类对象可以当做基类的对象来使用称作向上转型
(upcasting),
反之称为向下转型
(downcasting).
动态绑定和多态
动态绑定是指在执行期间
(
而非编译期
)
判断所引用对象的实际类型
,
根据其实际的类型调用其相应的方法
.
实际中
new
的谁就调用谁的方法
,
实际中的地址才会绑定到相应方法之中的地址上面
多态的条件
:
1
有继承
2
有重写
3
父类引用指向子类对象
多态特性对于系统可扩充性有重要影响
抽象类
用
abstract
关键字来修饰一个类时
,
这个类叫做抽象类
,
用
abstract
来修饰一个方法时
,
该方法叫做抽象方法
.
含有抽象方法的类必须被声明为抽象类
,
抽象类必须被继承
,
抽象方法必须被重写
.
抽象类不能被实例化
抽象方法只需声明
,
不需实现
Eg:public abstract void enjoy();
Final
关键字
Final
的变量值不能够被改变
Final
的成员变量
Final
的局部变量
(
形参
)
Final
的类不能够被继承
Final
的方法不能够被重写
Public class TestFianl{
Public static void main(String[] args){
T t = new T();
t.i = 9;
}
}
Final Class T{
Final int t = 8;
Public final void m(final int j){
}
}
Class TT extends T{
Public void m(){
}
}
接口interface
多个无关的类可以实现同一个接口
一个类可以实现多个无关的接口
与继承关系类似
,
接口与实现类之间存在多态性
接口是抽象方法和常量值的定义的集合
从本质上讲
,
接口是一种特殊的抽象类
,
这种抽象类中只包含常量和方法的定义
,
而没有变量和方法的实现
接口特性
接口可以多重实现
接口中声明的属性默认为
public static final
的
;
也只能是
public static final
的
;
接口中只能定义抽象方法
,
而且这些方法默认为
public
的
,
也只能是
public
的
;
接口可以继承其它的接口
,
并添加新的属性和抽象方法
.
异常处理
运行期出现的错误
Eg: int[] a = {1,2,3};
Try{
System.out..println(arr[4]);
}
Catch(ArrayIndexOutofBoundsException ar){
System.out.println(“
系统正在维护
”);
ar.printStackTrace();
}
Java.lang.ArrayIndexOutofBoundsException
数组下标越界
printStackTrace();
j2sdk
中定义了很多异常类
Throwable (1)error
不可处理
(2)exception / RuntimeException
经常出现的错误
,
可以捕获也可以不捕获
./
另一类必须被
catch
Try{}
Catch(someException1 e){}
Catch(someException2 e){}
Finally{}//
通常在其中进行资源的清除工作
Void f() throws FileNotFoundException,IOException{}
Void f2(){
Try{
f(0);
}catch(FileNotFoundException e){
System.out.println{e.getMessage()}}
Catch(IOException e){
e.printStackTrace();}
}
ArithmeticException
Try catch finally throws throw
使用自定义异常一般有如下步骤
;
1
通过继承
java.lang.Exception
类声明自己的异常类
2
在方法适当的位置生成自定义异常的实例
,
并用
throw
语句抛出
3
在方法的声明部分用
throws
语句声明该方法可能抛出的异常
注意
:
重写方法需要抛出与原方法所抛出异常类型一致异常或不抛出异常
数组
一维数组的声明方式
: type var[]
或
type[] var
数组对象的创建
:
Java
中使用关键字
new
创建数组对象
,
格式为
:
数组名
= new
数组元素的类型
[
数组元素的个数
]
Eg public class test{
Public static void main(String args[]){
Int[] s;
S = new int[5];
For(int i = 0; i < 5; i++){
S[i] = 2*i+1;
}
}
}
注意
:
数组元素为引用数据类型的数组中的每一个元素都需要实例化
.
Public class Test{
Public static void main(String args[]){
Date[] days;
days=new Date[3];
for(int i=0;i<3;i++){
days[i]=new Date(2004,4,i+1);
}
}
}
class Date{
int year; int month; int day;
Date(int y, int m, int d){
Year = y;
Moth = m;
Day = d;
}
}
数组初始化
动态初始化
:
数组定义与为数组元素分配空间和赋值的操作分开进行
.
Eg public class Test{
Public static void main(String args[]){
Int a[];
A = new int[3];
A[0]=3,a[1]=9,a[2]=8;
Date days[];
Days = new Date[3];
Days[0]=new Date(1,4,2004);
Days[1]=new Date(2,4,2004);
Days[2]=new Date(3,4,2004);
}
}
Class Date{
Int year,month,day;
Date(int y,int m,int d){
year=y,month=m,day=d;
}
}
静态初始化
:
在定义数组的同时就为数组元素分配空间并赋值
.
Public class test{
Public static void main(String args[]){
Int a[] = {3,9,8};
Date days[] = {new Date(1,4,2004), new Date(2,4,2004),new Date(3,4,2004)}
}
}
Class Date{
Int year,month,day;
Date(int y,int m,int d){
year=y,month=m,day=d;
}
}
数组元素的默认初始化
数组是引用类型
,
它的元素相当于类的成员变量
,
因此数组分配空间后
,
每个元素也被按照成员变量的规则被隐式初始化
.
Public class test{
Public static void main(String args[]){
Int a[] = new int[5];
Date[] days = new Date[3];
System.out.println(a[3]);
System.out.println(days[2]);
}
}
Class date{
Int year,month,day;
Date(int y,int m,int d){
Year=y;
Month=m;
Day=d;
}
}
输出结果
:0,null
数组元素的引用
定义并用运算符
new
为之分配空间后
,
才可以引用数组中的每个元素
,
数组元素的引用方式为
:arrayName[index]
Index
可以为数组元素下标
,
可以是整形常量或整形表达式
.eg a[3] b[i] c[6*i]
数组元素下标从
0
开始
;
长度为
n
的数组的合法下标取值范围为
0~n-1
每个数组都有一个属性
length
指明它的长度
,
例如
a.
length
的值为数组
a
的长度
(
元素个数
)
public class TestArray{
public static void main(String[] args){}
int[] a = {2,4,6,7,3,5,1,9,8};
for(int i=0;i<a. .length;i++){
System.out.println(a[i] + “ ”);
}
For(int i=0;i<args.length;i++){
System.out..println(args[i]);
}
}
Public class TestArgs{
Public static void main(String[] args){
If(args.length<3){
System.out.println(“usage:java Test \”n1\” \”op\” \” n2\””);
System.exit(-1); //
非正常退出
}
double d1 = Double.parseDouble(args[0]);
double d2 = Double.parseDouble(args[2]);
double d = 0;
if(args[1].equals(“+”)) d = d1+d2;
else if(args[1].equals(“-”)) d = d1-d2;
else if(args[1].eauals(“
×
”)) d=d1*d2;
else if(args[1].equals(“/”)) d=d1/d2;
else{
System.out.println(“Error operator!”);
System.exit(-1);
}
System.out.println(d);
}
}
*******************
Public class NumSort{
Public static void main(String[] args){
int[] a = new int[args.length];
//
读进来
for(int i=0;i<args.length;i++){
a[i] = Integer,parseInt(args[i]);
}
print(a);
selectionSort(a);
print(a);
}
Private static void selectionSort(int[] a){
int k,temp;
For(int i=0;i<a.length;i++){
k = i;
for(int j=k+1;j<a.length;j++){
If(a[j]<a[k]){
k = j;
}
}
If(k!=i){
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
Private static void print(int[] a){
For(int i=0;i<a.length;i++)
{
System.out.print(a[i] + “ “);
}
System.out.println();
}
}
Public class Test{
Public static void main(String[] args){
Date[] days = new Date[10];
Date day = new Date(2004,4,6);
}
Class Date{
Int year,month,day;
Date(int y,m,d){}
}
}
二维数组
可以看成以数组为元素的数组
多维数组的声明和初始化应该按从高维到低维的顺序进行
.
Eg int a[][] = new int[3][ ]
A[0] = new int[2];
A[1] =new int[4];
A[2] = new int[3]
数据的拷贝
使用
java.lang.System
类的静态方法
Public static void arraycopy(object src,int srcPos,object dest,int destPos,int length)
可以用于数组
src
从第
srcPos
项元素开始的
length
个元素拷贝到目标数组从
destPos
项开始的
length
个位置
.
如果源数据数目超过目标数组边界会抛出
IndexOutOfBoundsException
异常
.