最近有些时间整理一下Java语言的基础知识,温故知新也是一件好事,如果能帮助想入门Java的人就更好了。众所周知Java是一门伟大的计算机编程语言,号称一次编译,到处运行。事实也证明它是通过JVM虚拟机屏蔽了不同操作系统的差异性,也算实现了它的承诺。
代码规范
1.命名规范
(1)所有的标示符建议使用(A-Z或a-z)、数字(0-9)和下划线“”。
(2)包名全部小写字母。例如:www.tonysun.cc
(3)类名、接口名采用帕斯卡命名法。例如:Tony。
(4)变量名、方法名采用骆驼命名法。例如:setNeekeName(String neekeName)。
(5)常量的声明应该全部大写,每个单词之间用“”连接。例如:final String WWW_TONY_CN = “www.tonysun.cc”;
2.注释规范
(1)所有的代码源文件都应该在开头有一个注释说明,其中列出文件名、日期、开发者和类的功能概述。
(2)每个方法必须添加文档注释(类的main()方法除外)。
(3)每个属性必须添加注释。
(4)代码中至少包含15%的注释。
3.文件名规范
(1)一个Java源文件只能存储一个Java类。
(2)文件名与Java类名相同。
(3)一个类文件的代码行不超过200行。
程序常量
程序运行过程中不能改变的值。
- 代表常数,便于程序的修改(例如:圆周率的值)
- 增强程序的可读性(例如:常量UP、DOWN、LEFT和RIGHT分辨代表上下左右,其数值分别是1、2、3和4)
常量的语法格式和变量类型,只需要在变量的语法格式前面添加关键字final即可。在Java编码规范中,要求常量名必须大写。
则常量的语法格式如下:
final 数据类型 常量名称 = 值;
final 数据类型 常量名称1 = 值1, 常量名称2 = 值2,……常量名称n = 值n;
例如:
final double PI = 3.14;
final char MALE=‘M’,FEMALE=‘F’;
程序变量
变量就是指代在内存中开辟的存储空间,用于存放运算过程中需要用到的数据,在Java语言中变量分为实例变量和静态变量。
全局变量
对整个应用程序可见的变量,在Java中由public修饰的static变量可以称的上是全局变量。
public class Utitl{
public double PI=3.1415426;
}
成员变量
在 Java 语言中成员变量是相对于Java对象而说的,一个对象拥有的所有属性即为当前对象的成员变量,对象的方法以成员方法的形式存在。
public class Person{
private string id;
private string name;
public void setId(string sid){
this.id=sid;
}
public void getId(){
return this.id;
}
public void setName(string sname){
this.name=sname;
}
public void getName(){
return this.name;
}
}
在Person类中id、name为成员变量,也为Person类型对象的属性。一般成员变量的作用范围都只限于对象内部使用,如果外部需要访问时只能通过成员方法对其获取。如 getId、setId等。
局部变量
一般定义在方法中的变量都是局部变量,其作用范围只限于方法内部有效。局部变量的生命周期和方法的生命周期一致,调用该方法声明该局部变量并初始化,该局部变量被创建并分配内存空间;直到该方法调用结束局部变量也就结束了。
public class Person{
private string id;
private string name;
public void setId(string sid){
this.id=sid;
}
public void getId(){
return this.id;
}
public void setName(string sname){
this.name=sname;
}
public void getName(){
return this.name;
}
public void getMyName(){
string tempName=“我的名字:”+this.name;
return tempName;
}
}
如以上代码中 tempName变量在执行getMyName方法的时候被在方法内部创建并分配内存。方法执行完毕时tempName变量可被回收释放。
代码注释
代码注释对一个程序员来说尤为重要,更是衡量程序员是否合格的重要指标。这可以帮助程序员快速了解代码的组成部分和作用。
- 单行注释 //注释的内容
- 多行注释 /…/
- Javadoc的标记
@version 指定版本信息
@since 指定最早出现在哪个版本
@author 指定作者
@see 生成参考其他的JavaDoc文档的连接
@link 生成参考其他的JavaDoc文档,它和@see标记的区别在于,@link标记能够嵌入到注释语句中,为注释语句中的特殊词汇生成连接。 eg.{@link Hello}
@deprecated 用来注明被注释的类、变量或方法已经不提倡使用,在将来的版本中有可能被废弃
@param 描述方法的参数
@return 描述方法的返回值
@throws 描述方法抛出的异常,指明抛出异常的条件
如下代码如示:
/**
@javadoc注释的内容
*/
public class Hello{
/**属性上的注释*/
public String name;
/**这是main方法,是程序的入口
*@param args 用户输入参数
*/
public static void main(String[] args){
System.out.println("Hello World!");
f1();
}
/** 这是第1个方法,其作用是...*/
public static void f1(){
System.out.println("f1()!");
}
}
关键字
是java语言的系统保留字,java编译器通过这些保留字解析我们开发的应用程序,所有关键字在我们代码中是不能被做为变量、方法、类型等命名使用的。
private 一种访问控制方式:私用模式
protected 一种访问控制方式:保护模式
public 一种访问控制方式:共用模式
abstract 表明类或者成员方法具有抽象属性
class 类
extends 表明一个类型是另一个类型的子类型,这里常见的类型有类和接口
final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变
implements 表明一个类实现了给定的接口
interface 接口
new 用来创建新实例对象
static 表明具有静态属性
synchronized 表明一段代码需要同步执行
break 提前跳出一个块
continue 回到一个块的开始处
return 从成员方法中返回数据
do 用在do-while循环结构中
while 用在循环结构中
if 条件语句的引导词
else 用在条件语句中,表明当条件不成立时的分支
for 一种循环结构的引导词
instanceof 用来测试一个对象是否是指定类型的实例对象
switch 分支语句结构的引导词
case 用在switch语句之中,表示其中的一个分支
default 默认,例如,用在switch语句中,表明一个默认的分支
**try 尝试一个可能抛出异常的程序块
catch 用在异常处理中,用来捕捉异常
throw 抛出一个异常
throws 声明在当前定义的成员方法中所有需要抛出的异常
import 表明要访问指定的类或包
package 包
boolean 基本数据类型之一,布尔类型
byte 基本数据类型之一,字节类型
char 基本数据类型之一,字符类型
double 基本数据类型之一,双精度浮点数类型
float 基本数据类型之一,单精度浮点数类型
int 基本数据类型之一,整数类型
long 基本数据类型之一,长整数类型
short 基本数据类型之一,短整数类型
null 空
true 正确
false 错误
super 表明当前对象的父类型的引用或者父类型的构造方法
this 指向当前实例对象的引用
void 声明当前成员方法没有返回值
goto 保留关键字,没有具体含义
const 保留关键字,没有具体含义
数据类型
变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
值类型
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte:
byte 数据类型是8位、有符号的,以二进制补码表示的整数;
最小值是 -128(-2^7);
最大值是 127(2^7-1);
默认值是 0;
byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一;
例子:byte a = 100,byte b = -50。
short:
short 数据类型是 16 位、有符号的以二进制补码表示的整数
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
Short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一;
默认值是 0;
例子:short s = 1000,short r = -20000。
int:
int 数据类型是32位、有符号的以二进制补码表示的整数;
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
一般地整型变量默认为 int 类型;
默认值是 0 ;
例子:int a = 100000, int b = -200000。
long:
long 数据类型是 64 位、有符号的以二进制补码表示的整数;
最小值是 -9,223,372,036,854,775,808(-2^63);
最大值是 9,223,372,036,854,775,807(2^63 -1);
这种类型主要使用在需要比较大整数的系统上;
默认值是 0L;
例子: long a = 100000L,Long b = -200000L。
"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。
float:
float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;
float 在储存大型浮点数组的时候可节省内存空间;
默认值是 0.0f;
浮点数不能用来表示精确的值,如货币;
例子:float f1 = 234.5f。
double:
double 数据类型是双精度、64 位、符合IEEE 754标准的浮点数;
浮点数的默认类型为double类型;
double类型同样不能表示精确的值,如货币;
默认值是 0.0d;
例子:double d1 = 123.4。
boolean:
boolean数据类型表示一位的信息;
只有两个取值:true 和 false;
这种类型只作为一种标志来记录 true/false 情况;
默认值是 false;
例子:boolean one = true。
char:
char类型是一个单一的 16 位 Unicode 字符;
最小值是 \u0000(即为0);
最大值是 \uffff(即为65,535);
char 数据类型可以储存任何字符;
例子:char letter = ‘A’;。
引用类型
每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”。
在 Java 中一切都被视为了对象,但是我们操作的标识符实际上是对象的一个引用(reference)。Java内部将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。
强引用
Java中默认声明的就是强引用,比如:
Object obj = new Object(); //只要obj还指向Object对象,Object对象就不会被回收
obj = null; //手动置null
只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了。
软引用
软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。
弱引用
弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。
虚引用
虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。
引用队列
引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。
数组类型
数组是一种数据结构,用来存储同一类型之的集合。通过一个整形下标可以访问数组中的每一个值。
在声明数组变量时,需要指出数据类型和数组变量的名字。下面声明了整形数组a:
int[] a;
这条语句之声明了变量啊,病没有将a初始化为一个正真的数组。应该使用new运算符创建数组。
int [] a = new int[100];
数组长度不要求是常量,new int[n]将会创建一个长度为n的数组
可以使用下面两种形式声明数组
int[] a 或 int a[]
创建一个数字数组时,所有元素都初始化为0。boolean数组的元素会初始化为false。对想数组的元素则初始化为一个特殊值null。
一旦创建了数组,就不能改变它的大小。
集合类型
Java集合框架主要包括两种类型的容器,一种是集合(Collection),另一种是图(Map)。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等。Map常用的有HashMap,LinkedHashMap等。
List
List接口扩展自Collection,它可以定义一个允许重复的有序集合,从List接口中的方法来看,List接口主要是增加了面向位置的操作,允许在指定位置上操作元素,同时增加了一个能够双向遍历线性表的新列表迭代器ListIterator。AbstractList类提供了List接口的部分实现,AbstractSequentialList扩展自AbstractList,主要是提供对链表的支持。下面介绍List接口的两个重要的具体实现类,也是我们可能最常用的类,ArrayList和LinkedList。
ArrayList
用数组存储元素,这个数组可以动态创建,如果元素个数超过了数组的容量,那么就创建一个更大的新数组,并将当前数组中的所有元素都复制到新数组中。
LinkedList
在学习数据结构的时候,我们知道链表和数组的最大区别在于它们对元素的存储方式的不同导致它们在对数据进行不同操作时的效率不同,同样,ArrayList与LinkedList也是如此,实际使用中我们需要根据特定的需求选用合适的类,如果除了在末尾外不能在其他位置插入或者删除元素,那么ArrayList效率更高,如果需要经常插入或者删除元素,就选择LinkedList。
CopyOnWriteArrayList
CopyOnWriteArrayList,是一个线程安全的List接口的实现,它使用了ReentrantLock锁来保证在并发情况下提供高性能的并发读取。
Set
Set接口扩展自Collection,它与List的不同之处在于,规定Set的实例不包含重复的元素。在一个规则集内,一定不存在两个相等的元素。AbstractSet是一个实现Set接口的抽象类,Set接口有三个具体实现类,分别是散列集HashSet、链式散列集LinkedHashSet和树形集TreeSet。
HashSet
散列集HashSet是一个用于实现Set接口的具体类,可以使用它的无参构造方法来创建空的散列集,也可以由一个现有的集合创建散列集。
LinkedHashSet
LinkedHashSet是用一个链表实现来扩展HashSet类,它支持对规则集内的元素排序。HashSet中的元素是没有被排序的,而LinkedHashSet中的元素可以按照它们插入规则集的顺序提取。
TreeSet
TreeSet扩展自AbstractSet,并实现了NavigableSet,AbstractSet扩展自AbstractCollection,树形集是一个有序的Set,其底层是一颗树,这样就能从Set里面提取一个有序序列了。在实例化TreeSet时,我们可以给TreeSet指定一个比较器Comparator来指定树形集中的元素顺序。树形集中提供了很多便捷的方法。
Queue
队列是一种先进先出的数据结构,元素在队列末尾添加,在队列头部删除。Queue接口扩展自Collection,并提供插入、提取、检验等操作。
HashMap
HashMap是基于哈希表的Map接口的非同步实现,继承自AbstractMap,AbstractMap是部分实现Map接口的抽象类。
LinkedHashMap
LinkedHashMap继承自HashMap,它主要是用链表实现来扩展HashMap类,HashMap中条目是没有顺序的,但是在LinkedHashMap中元素既可以按照它们插入图的顺序排序,也可以按它们最后一次被访问的顺序排序。
TreeMap
TreeMap基于红黑树数据结构的实现,键值可以使用Comparable或Comparator接口来排序。TreeMap继承自AbstractMap,同时实现了接口NavigableMap,而接口NavigableMap则继承自SortedMap。SortedMap是Map的子接口,使用它可以确保图中的条目是排好序的。
ConcurrentHashMap
Concurrent,并发,从名字就可以看出来ConcurrentHashMap是HashMap的线程安全版。同HashMap相比,ConcurrentHashMap不仅保证了访问的线程安全性,而且在效率上与HashTable相比,也有较大的提高。
运算符
算术运算符
+ 加法: 相加运算符两侧的值 A + B 等于 30
- 减法: 左操作数减去右操作数 A – B 等于 -10
*乘法: 相乘操作符两侧的值 A * B等于200
/除法: 左操作数除以右操作数 B / A等于2
%取余: 左操作数除以右操作数的余数 B%A等于0
++自增: 操作数的值增加1 B++ 或 ++B 等于 21(区别详见下文)
– 自减: 操作数的值减少1 B-- 或 --B 等于 19(区别详见下文)
关系运算符
==相等: 检查如果两个操作数的值是否相等,如果相等则条件为真。
!= 不相等: 检查如果两个操作数的值是否相等,如果值不相等则条件为真。
>大于: 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。
< 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。
>=大于等于: 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。
<=小于等于: 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。
位运算符
& 如果相对应位都是1,则结果为1,否则为0 。
| 如果相对应位都是 0,则结果为 0,否则为 1 。
^ 如果相对应位值相同,则结果为0,否则为1。
〜 按位取反运算符翻转操作数的每一位,即0变成1,1变成0。
<< 按位左移运算符。左操作数按位左移右操作数指定的位数。
逻辑运算符
操作符 描述 例子
&& 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 (A && B)为假。
| | 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 (A | | B)为真。
! 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 !(A && B)为真。
条件运算符
variable x = (expression) ? value if true : value if false
instanceof 运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
( Object reference variable ) instanceof (class/interface type)
流程控制
复合语句
Java语言的复合语句是以整个块区为单位的语句,又称块语句。复合语句由“{”开始,“}”结束。
对于复合语句,我们只需要知道,复合语句为局部变量创建了一个作用域,该作用域为程序的一部分,在该作用域中某个变量被创建并能够被使用,如果在某个变量的作用域外使用该变量,则会发生错误。并且复合语句中可以嵌套复合语句。
条件语句
条件语句可根据不同的条件执行不同的语句。包括if条件语句与switch多分支语句。这是学习Java的一个基础与重点。
1. if条件语句
使用if条件语句,可选择是否要执行紧跟在条件之后的那个语句。关键字if之后是作为条件的“布尔表达式”,如果该表达式返回true,则执行其后的语句;若为false,则不执行if后的语句。可分为简单的if条件语句、if···else语句和if···else if多分支语句。
2. if···else语句
if···else语句是条件语句中最常用的一种形式,它会针对某种条件有选择的作出处理。通常表现为“如果满足某种条件,就进行某种处理,否则就进行另一种处理”。
3. if···else if多分支语句
if···else if多分支语句用于针对某一事件的多种情况进行处理。通常表现为“如果满足某种条件”,就进行某种处理,否则,如果满足另一种条件,则进行另一种处理。
4. switch多分支语句
switch语句是一种比较简单明了的多选一的选择,在Java语言中,可以用switch语句将动作组织起来进行多选一。
循环语句
循环语句就是在满足一定条件的情况下反复执行某一个操作。包括while循环语句、do···while循环语句和for循环语句。
1. while循环语句
while循环语句的循环方式为利用一个条件来控制是否要继续反复执行这个语句。
2. do···while循环语句
do···while循环语句与while循环语句的区别是,while循环语句先判断条件是否成立再执行循环体,而do···while循环语句则先执行一次循环后,再判断条件是否成立。也即do···while至少执行一次。
3. for循环语句
for循环语句是Java程序设计中最有用的循环语句之一。一个for循环可以用来重复执行某条语句,知道某个条件得到满足。语法格式如下:
for(表达式1; 表达式2; 表达式3)
{
语句序列
}
跳转语句
Java语言提供了三种跳转语句,分别是break语句、continue语句和return语句。
1. break语句
break语句刚刚在switch中已经见过了,是用来中止case的。实际上break语句在for、while、do···while循环语句中,用于强行退出当前循环,为什么说是当前循环呢,因为break只能跳出离它最近的那个循环的循环体,假设有两个循环嵌套使用,break用在内层循环下,则break只能跳出内层循环,如下:
for(int i=0; i<n; i++) { // 外层循环
for(int j=0; j<n ;j++) { // 内层循环
break;
}
}
2. continue语句
continue语句只能用于for、while、do···while循环语句中,用于让程序直接跳过其后面的语句,进行下一次循环。
3. return语句
return语句可以从一个方法返回,并把控制权交给调用它的语句。