1 Core Java 基础
1.1 Java 基础知识
1.1.1 概述
java语言是解释执行,java源码是通过编译生成一种特殊的.class的中间字解码文件,然后再有JVM进行解释执行。
java语言对指针进行了上层的封装,它保证能够通过这个指针(引用),来访问有效的内存单元。
java语言不允许多继承,使继承关系成树装图,每个类都只能由一个父类。
java语言的开发效率高,但执行效率低(相当于c++的55%)。
java的垃圾回收机制,在java中new的对象不需要向c++一样进行delete操作,JVM会根据情况回收垃圾对象。(懒汉机制,等待资源没有的时候才回收)
我们只能够建议JVM进行垃圾回收,例如∶System.gc() ,RunTime.gc()这两个方法就是建议JVM进行垃圾回收的方法。
JDK,java开发工具包(类库和运行命令),JRE,java运行环境,JVM,java虚拟机(解释执行的核心,对字节码进行翻译成运行环境的机器码,它可以屏蔽平台差异。JVM是不跨平台的。)
- JAVA_HOME,指明JDK安装的位置,
- CLASSPATH,指明类文件的位置,
- PATH,指明命令的可执行文件的位置。
java源文件的文件名必须和文件中定义public class的类名(大小写页要相同)相同。
java源代码中的main方法是程序的入口,下面是main方法的定义写法。
public static void main(String[] args){
System.out.println("Hello world");
}
java源文件也要先编译,使用javac xxx.java格式的命令得来编译,使用java xxx来运行。
1.1.2 包
- 定义包结构要放在有效代码的第一行,package xxx.xxx,
- 包的定义在一个程序中只能由一个,
- 在加上包定义之后编译可以使用javac -d 路径 xxxx.java,这个-d这个命令行的参数可以指定包结构的位置
- 在运行时要使用类的全名
- java xxx.xxx.xxxx用包名以点分隔。
- 运行时要在包结构的上一层目录来运行。
实例:
/**
本文件为:E:/Tomcat 5.5/webapps/northhujia/src/NorthhujiaUtil.java
javac NorthhujiaUtil.java -d ../WEB-INF/classes/
java com.jc.hujd.NorthhujiaUtil
*/
package com.jc.hujd;
import java.io.*;
public class NorthhujiaUtil{
public static void main(String[] args){
System.out.println(NorthhujiaUtil.escapeHtml("<html>/"="));
}
public static String escapeHtml(String str){
if( str == null ){
return null;
}
int len = str.length();
StringBuffer sb = new StringBuffer(len);
for(int i=0; i<len; i++){
char c = str.charAt(i);
switch( c ){
case ' ':
sb.append(" ");
break;
case '<':
sb.append("<");
break;
case '>':
sb.append(">");
break;
case '&':
sb.append("&");
break;
case '"':
sb.append("quot;");
break;
default:
sb.append(c);
}//end switch
}//end for
return sb.toString();
}
}
编译和运行方式
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.
E:/Tomcat 5.5/webapps/northhujia/src>javac NorthhujiaUtil.java -d ../WEB-INF/classes/
E:/Tomcat 5.5/webapps/northhujia/src>cd ../WEB-INF/classes
E:/Tomcat 5.5/webapps/northhujia/WEB-INF/classes>java com.jc.hujd.NorthhujiaUtil
<html>quot;=
E:/Tomcat 5.5/webapps/northhujia/WEB-INF/classes>
1.1.3 java中的注释
- 单行注释
//......
- 多行注释
/* .......*/
- 文档注释
- 用javadoc命令可以根据原码中的文档注释生成注释文档(html格式)
- 文档注释中可以使用html标签。
- javadoc -d 路径 (指定注释文档的保存路径)
- 文档注释一般写在类定义之前,方法之前,属性之前。
/** <p>this is a class </p>
*/
- 在文档注释中可以用
- @author 表示程序的作者,
- @version 表示程序的版本,要写在类定义之前
- @param 对参数进行注释
- @return 对返回值进行注释
- @throws 对抛出异常的注释
1.1.4 jar命令
jar命令∶用于打一个xxx.jar文件
用法:jar {ctxu}[vfm0Mi] [jar-文件] [manifest-文件] [-C 目录] 文件名 ...
选项:
-c 创建新的存档
-t 列出存档内容的列表
-x 展开存档中的命名的(或所有的〕文件
-u 更新已存在的存档
-v 生成详细输出到标准输出上
-f 指定存档文件名
-m 包含来自标明文件的标明信息
-0 只存储方式;未用ZIP压缩格式
-M 不产生所有项的清单(manifest〕文件
-i 为指定的jar文件产生索引信息
-C 改变到指定的目录,并且包含下列文件:
如果一个文件名是一个目录,它将被递归处理。清单(manifest〕文件名和存档文件名都需要被指定,按‚m' 和 'f‘标志指定的相同顺序
示例1:将两个class文件存档到一个名为 ‚classes.jar‘ 的存档文件中:
jar cvf classes.jar Foo.class Bar.class
示例2:用一个存在的清单(manifest)文件 mymanifest 将 foo/ 目录下的所有文件存档到一个名为 classes.jar 的存档文件中:
jar cvfm classes.jar mymanifest -C foo/ .
一般在使用使用
jar cvf 文件名.jar 文件所在路径(xxx/xxx/xxx.class)
也可以压缩一个目录,只要在制定路径是指定为文件夹,jar命令的命令行参数在使用时可以以“-”开头,也可以不用。
java程序的运行过程:
- 启动java虚拟机
- 找.class文件
- 先从系统的类库中找(系统只会在跟目录下查找,所以需要完整类名)
- 再去CLASSPATH所设置的目录去找
- 将类文件加载到java虚拟机中
如果要使用到其他的在JAVA_HOME中没有的类或者是其他公司提供的第三方的.jar(jar包)文件时,要把它的路径及文件名加到CLASSPATH中。
import 包名,导入包中的类文件。
java.lang包 | 基础包。系统会在每个java程序中隐含导入 |
java.util包 | 工具类。 |
java.io包 | 输入输出操作 |
java.net包 | 网络编程。 |
java.awt,java.swing,javax.swing java.event包 | java的图形编程 |
java应用程序中必须有一个main()方法。
1.2 标识符和关键字
1.2.1 Java代码中的“;”、“{}”、“ ”
Java语句以分号分隔,Java代码块包含在大括号内,忽略空格。
1.2.2 ※标识符
- 用以命名类、方法和变量、以及包遵守JAVA的命名规范类以每个单词。方法和变量第一个字母不大写,其他都以大写字母开头。
- 只能以字符、“_”或“$”开头;
- 无长度限制。
1.2.3 ※java中的关键字
- goto和const在java中虽然不再使用但是还作为关键字存在。
- java中没有sizeof关键字了
- java中的boolean类型的值只能用true和false,且这两值也是关键字。
- java语言中没有无符号(unsigned)关键字。
1.3 java中的数据类型
- 整型
byte | 1字节 | 8位 | -128到127 |
short | 2字节 | 16位 | -2^15到2^15–1 |
int | 4字节 | 32位 | -2^31到2^31–1 |
long | 8字节 | 64位 | -2^63到2^63–1 |
- 浮点类型
float | 4字节 | 32位 |
double | 8字节 | 64位 |
- 字符类型
char | 2字节 | 16位 |
- 布尔型
boolean | false/true |
1.3.1 注意:
- char是无符号的16位整数,字面值必须用单引号括起来; ‘a’
- String 是类,非原始数据类型;
- 长整型数字有一个后缀为“L”或“l”,八进制前缀为“0”,十六进制前缀为“0×”;- 黙认浮点类型为double;
- float数据类型有一个后缀为“f”或“F”,Double数据类型后可跟后缀“D”或“d”;
- char类型也可以用通用转译字符,但是不能用ASCII码。可以用“/u0000”这种格式,因为char型中使用的是unicode编码方式。
- 整型值存放,正数存放原码(二进制码),负数则存放补码(原码按位取反末位加一)。
- 实型值在存储时会损失精度,所以不要直接比较两个实型值。
- 系统默认的实型都是double型,要使用float型时要在数据后加个f,或者强行转换,强转(占字节数大的类型转到占字节数小的类型)时会放弃高位值只取低位值。
- java中的数字数据类型转换由占字节数小的类型到占字节数大的类型的可以有自动转换,反之则需要强行转换,char型和int型之间可以相互转换。char和short不能相互转换。
1.3.2 隐式类型转换;
- a 运算符 b
- 如果a,b中有任意一个是double型,前面运算的结果就是double型
- 如果a,b中有任意一个是float型,前面运算的结果就是float型
- 如果a,b中有任意一个是long型,前面运算的结果就是long型
- 如果a,b中没有double、float、long型,那么其结果就为int型。
所有基本数据类型在使用时会事先分配空间,值本身就存在空间中,在传递时,就是值传递,不是引用传递。
static修饰的方法是类方法,否则是属于对象的方法
例如
public class Test{
public static void main(String[] args){
Test t=new Test(); int b=1; int c=2; int[] a=new int[10];
t.sqort(a); add(b,c)
}
public int[] sqort(int[] a){
.......
}
static int add(b,c){
.......
}
}
1.4 java中的运算符(java的运算符的优先级和结合性和c++相同)
System.out.println(3/2) 按整型计算 得1
>>= | 前面是零补零,前面是一补一; |
>>>= | 无符号右移(强制右移都会移进一), |
&& | 短路与,前面为假,表达式为假,后面的操作不会进行,& 会对所有条件进行判断 |
双竖线 | 短路或,前面为真,表达式为真,后面的操作不会进行, |
单竖线 | 会对所有条件进行判断。 |
instanceof | 判断一个对象是否属于某个类型 |
java中的求余运算符“%”可以对两个实型变量求余 |
1.4.1 注:
- 例:
- if(a<3&(b=a)==0) b赋值
- if(a<3&&(b=a)==0) b不赋值
- 使用左右位移和无符号右移运算符的使用方法是 变量名<<=位移位数 ,变量名>>=位移位数(前两个运算符是不会忽略整形符号位,也称逻辑位移),变量名>>>=位移位数
- 左右位移和无符号右移运算符只能用于整形及其兼容类型(byte,int,short,long)
- >>=和>>>=对于负数不一样
- 正数:右移n位等于除以2的n次方
- 负数:变成正数。
- 按位与是为了让某些位置一,按位或是令某些位置零,按位异或是令某些位取反。
1.5 java 语句
1.5.1 ※java的流程控制
- 控制流
- if()
- if()….else
- if()…..else if()….else
注意:else只是和其上面的同层的最近的if()来配对。
switch(){
case 'a':……..
case 1:……break;
default:
…………
}
注解:
- switch()内数据类型为byte short char int类型,只有以上四种类型的才可以在switch()中使用。
- case块中不加break时会按顺序执行下面的语句。
循环语句
- for(int i=0;i<n;i++){}
- while(){}
- do{} while();-----------注意加分号
例子:
loop:for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(3==j){
break loop;
/*loop为标签 只能用在循环语句中,循环
嵌套中用于跳到外层循环*/
}
}
}
辨析:
int x,a=6,b=7;
x=a++ + b++; // a=7,b=8,x=13
- break,跳出本层循环,执行后面的代码,
- continue,提前终止本次循环,再一次进行循环或循环条件满足或不满足后退出循环。
- break 标签名; continue 标签名;这两条语句知识表示跳出有标签的循环和提前终止本次有标签的循环,只能用在循环语句(多层循环嵌套)中,循环嵌套中用于跳到外层循环。
注意:
- for循环在使用时一定要注意不要忘记()中的两个„;“,死循环的写法for(;;){}或者是用while(true){}
注意:
- System.out.println(„…“+a)在使用这个语句时,它会将其中非字符串(String)的值转换成字符串(不是所有数据类型都可以的)。
1.6 数组
java中的数组Array,其包含两个部分,分别是数组的引用和数组的空间两部分。
1.6.1 声明数组
- 一组相同类型(可以是类)数据的集合;
- 一个数组是一个对象;
- 声明一个数组没有创建一个对象;
- 数组能以下列形式声明:
- int[] i 或 int i[]
- Car[] c 或 Car c[]
- 数组的定义 如:
- int[] a(数组引用声明)= new int[10](数组空间的声明,并把空间首地址赋值给数组的引用)
- int[] a; a=new int[20];
注:
- C++中只能 Car c[]
- JAVA中推荐用 Car[] c;
1.6.2 创建数组
- 创建基本数据类型数组
- int[] i = new int[2];
- 创建引用数据类型数组
- Car[] c = new Car[100];
- 数组创建后有初始值。
- 数字类型为0
- 布尔类型为false
- 引用类型为null
注:
- 访问没有初始化的数组中的值,是会抛出异常的(NULLpointerException),
- java中只保证一位数组的地址是连续的,二维数组实际上是一维数组中有存储了一维数组的引用。
1.6.3 初始化数组
初始化、创建、和声明分开
int[] i;
i = new int[2];
i[0] = 0;
i[1] = 1;
初始化、创建、和声明在同一时间
int[] i = {0,1};
Car[] c = {new Car(),new Car()};
1.6.4 多维数组
有效定义
int[][] i1 = new int[2][3]; (同时给定一维,二维的空间)
int[][] i2 = new int[2][]; (给定一维的空间,二维空间待定)
i2[0] = new int[2],i2[1] = new int[3];
- C++中 int[][] =new int[][3];有效
无效定义
int[][] i1 = new int[][3];
数组长度 -----数组的属性length(在二维数组中这个属性只代表第一维的长度)
int[] i = new int[5];
int len = i.length; //len = 5;
Student[][] st = new Student[4][6];
len = st.length; //len = 4;
len = st[0].length; //len = 6;
1.6.5 数组拷贝
System.arrayCopy(Object src, int srcPos, Object dest, int destPos, int length);
- src源数组,
srcPos从第几位开始拷贝, dest目标数组, destPos目标数组放置的起始位置, length,表示要拷贝的长度。拷贝一个数组到另一个数组。
1.6.6 类的对象的创建和对象数组
一个className.Java文件中可以定义多个类但是只能有一个public修饰的类,也只能以这个类的类名作为.java的文件名。
java中的类的对象的创建,
- 先创建这个对象的引用, 例如:Car c;
- 然后用new这个关键字创建一个对象的实例(对象的空间) 例如:c=new Car();,
- 然后对象的实例的空间首地址赋值给对象的引用。
注意:
- 多个对象的引用可以同时引用自同一个对象的实例,但是对象的引用只能引用一个对象的实例。
- 对象的引用和对象的实例间就像是牵着气球的线和气球一样。
- 只有一个没有被任何对象的引用所引用的对象的实例才会变成垃圾等待被垃圾回收。
1.6.7 对象数组
Car[] c=new Car[3];
c[0]=new Car();
注意:存放基本类型的数组的数据是直接存放在数组的空间中,而对象的数组在数组空间中存放的则是对象的引用。
- 定义在类中类的属性是实例变量
- 定义在类的方法中的变量是局部变量。
- 实例变量是保存在对象空间中的,
- 局部变量则是在方法调用的分配空间,调用结束后就释放空间。
注:
- 在类的定义中属性的定义和方法的定义必须写在类里。
- 系统会自动初始化实例变量,数字类型为0 ,布尔类型为false ,引用类型为null。
- 局部变量需要初始化,必须赋初值。如果不赋初值无法通过编译。
Java中的方法调用中参数传递有两种,
- 参数是基本类型的使用的是值传递(直接传参数的值),
- 引用传递,它是用于参数是类的对象,它传递的是这个对象的引用。