★JAVA的特性
Simple简单(去掉了C++中许多奇怪的语法)
Object-Oriented面向对象(OOP)
Network-Savvy网络通信(支持HTTP,FTP,TCP/IP等多种网络协议)
Robust健壮性(健壮性主要体现在Java在编译是就能发现某些存在的问题,且优化了C和C++中的指针,不会造成内存泄露)
Secure安全性
Architecture Neutral体系结构中立
Portable可移植性(Java固定了数据类型的大小)
Interpreted解释型语言(存在争议,可能介于编译和解释之间)
High Performance高性能
Multiple-threaded多线程
Dynamic动态性
Java和C++的区别:Java去掉了C++中的头文件,指针运算,结构体,联合体以及运算符重载等语法,且Java以接口替代了C++中的多重继承
JIT(Just In Time)virtual machines have the option of translating the most frequently executed bytecodes sequences into machine code, a process called just-in-time compilation
★JAVA运行的环境
环境变量配置
在Windows下(XP):
--下载Windows版本的JDK,双击进行安装,建议安装目录C:\java\jdk1.6.0_06
--设置环境变量:
JAVA_HOME c:\java\jdk1.6.0_06
PATH 添加到原有路径的最前方,%JAVA_HOME%\bin(不要删除原来的)
CLASSPATH .;%JAVA_HOME%\lib
在Linux下:
--下载一个Linux Platform的JDK, 建议下载RPM自解压格式的(RPM in self-extracting file,jdk1.6.0_06-linux-i586-rpm.bin)
--在shell下执行命令:
chmod 755 jdk1.6.0_06-linux-i586-rpm.bin
./jdk1.6.0_06-linux-i586-rpm.bin
--设置环境变量 :
在Linux系统的用户主目录下新建终端vi.bash_profile在其中添加如下参数:
JAVA_HOME = /opt/jdk1.6.0_06
PATH = $JAVA_HOME/bin:.
CLASSPATH = .
export PATH
export CLASSPATH
上述配置完成后在命令提示行(Windows)或终端(Linux)运行java –version如果可以查看JDK的版本信息,则证明配置环境变量成功
编译、执行JAVA文件javac filename.java编译程序,java filename执行程序
注意:当使用java –classpath 执行程序的时候,这个classpath的优先级高于系统设置的classpath
★JAVA中的基础知识点
JAVA语言大小写敏感(case sensitive)
JAVA合法标识符的原则:字母、下划线、美元符为首字母,后面可以是任意长度的字母、数字、下划线和美元符的字符序列(但不能是JAVA的保留字)
JAVA语言的一般命名原则:(见文知意)
★对于类、接口:每个单词的首字母大写,一般不使用缩写。(名词)
★对于变量:首个单词小写,其后的每一个单词的首字母大写。(名词)
★对于方法:首个单词小写,其后的每一个单词的首字母大写。(动词)
★对于常量:全部大写。使用_进行连接(名词)
★对于包:全部小写,一般为公司组织域名的逆序。(名词)
JAVA的文件名必须和文件内的公有类名相同(一个源文件只能有一个public类)。注意:当文件中不存在公有类的时候:则源文件可以随意命名,只要符合JAVA语言的标识符规范即可
JAVA的注释:
// 单行注释,可用于源文件的任何位置
/*……*/ 多行注释,可用于源文件的任何位置
/**……*/ JAVA注释,使用javadoc命令可以生成HTML注释,可用于源文件的任何位置
方法注释的参数有@param、@return、@throws
文档注释一般参数有@author、@version、@since、@deprecated @see
将文档生成在指定目录javadoc -d docDirectory packageName
如果要生成的文档在多个包中javadoc -d docDirectory *.java
一个JAVA源文件可以不包含任何代码定义,即使它是一个空文件,编译也不会产生异常。(这里的空指的是类体内不包含任何代码)
关于main方法,完整定义为public static void main(String[] args)
public不是必须的,但是如果没有public修饰的话,编译不会出错,但是该程序因为JVM找不到执行入口而无法被执行
static是必须的,它可以在不构造实例的情况下调用main方法
返回值必须是void,不能定义为其他,定义为其他尽管不会产生编译错误,但是无法运行
args是一个字符串类型的数组,用于接收命令行参数。(可以不叫args)
args数组即使不接收任何参数,也会创建一个长度为0的数组
main方法的另一种形式public static void main(String...args)
这个例子值得注意,假设有两个类Employee和EmployeeTest,后者负责测试前者,如果两个类在两个文件中,javac Employee*.java可以同时编译两个文件,
但是如果是javac EmployeeTest.java呢?
答案是也可以编译通过,这里要说明的是,当JVM在编译EmployeeTest时,发现其中有Employee类,于是就去找Employee.class
如果找不到,JVM则会找Employee.java这个文件,找到后对其进行编译,然后再编译EmployeeTest
特别说明的是,如果找到的Employee.java时间戳早于Employee.class,那么JVM会重新编译Employee.java
★JAVA语言的程序结构
包语句(package):公司域名逆序。(除了注释的第一行)
编译时:javac com/suki/PayrollApp.java
运行时:java com.suki.PayrollApp
导入语句(import)(包语句之后,类声明之前)
注意:import java.util.*;
import java.sql.*;
如果同时想要使用这两个包中的Date类怎么办呢?
java.util.Date today = new java.util.Date();
java.sql.Date today = new java.sql.Date(...);
静态导入:静态导入实现无需在使用其他类的静态成员时前缀的类名,使代码更为简洁,import static
如:import static java.lang.Math;(针对静态方法)
import static java.lang.Math.*(针对静态属性和静态方法)
import static java.lang.Math.PI; (针对静态属性)这样在类中就能直接应用PI这个属性了
一般情况下不推荐使用静态导入,引起代码费解。(Math类比较适合使用静态导入)
类声明语句(class declaration)
★JAVA中的的数据类型
JAVA数据类型分为基本类型(primitive)和引用类型(reference)
其中基本类型包括:
★整型byte(1字节)、short(2字节)、int(4字节)、long(8字节)
★布尔型boolean(1个字节)
★浮点型float(4个字节)、double(8个字节)
★字符型char(2个字节)一个char可保存一个汉字。
注意:
★整型数据默认为 int 类型,如果使用long类型,则必须加后缀l或L,建议用L
★浮点型数据默认为double类型,如果使用float类型,则必须加后缀f或F。当然也可以在double类型后添加后缀D或d
★整型数据可以有三种,十进制,八进制(0为前缀),十六进制(0x为前缀)
★整型数据、浮点型数据除零的问题(见后的除法运算)
★浮点型数据运算不精确的问题(如2.0-1.1不等于0.9)见后的BigDecimal类
★特殊字符 \b退格 \n换行 \t制表符 \r回车 \\反斜杠 \\. 点等
★boolean类型的取值只有true和false。
★在赋值语句中,默认类型为整型的无小数点整型文字值作为右操作数时,可以将其赋值给取值范围比整型小的变量,如byte,前提是文字值对应的实际型数值在变量类型的取值范围内。而默认的double型的数据文字值不能赋给float类型
strictfp关键字
对于浮点型数据参与的运算,有可能由于处理器的不同而造成的结果的不同,比如Intel的处理器在处理浮点型数据的时候会把其转为80位浮点,而有些处理器则会按照64位浮点来运算,解决方法:strictfp关键字。
strictfp的意思是FP-strict,也就是说精确浮点的意思。在Java虚拟机进行浮点运算时,如果没有指定strictfp关键字时,Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以至于得到的结果往往无法令人满意。而一旦使用了strictfp来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。因此如果想让浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。
可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字。
一旦使用了关键字strictfp来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE-754规范的。例如一个类被声明为strictfp,那么该类中所有的方法都是strictfp的。
在JDK5中,有一个java.lang.StrictMath类来代替java.lang.Math类,就是因为Math的浮点运算会产生精确性问题。
JAVA中的变量初始化
★对于成员变量来说,系统会有默认的初始化:byte 0、short 0、int 0、long 0L、float 0.0f、double 0.0d、char \u0000、boolean false
★对于局部变量(定义在方法中的变量)则必须显式初始化,否则编译会出错;且局部变量只能在该方法体内使用,不能跨方法访问。可在不同的方法中声明同名的局部变量。
★对于数组元素,不论是基本类型的数组还是引用类型的数组,其都会默认初始化(同上)
JAVA中基本数据类型的转换:
自动转换:是系统根据转换规则自动完成的,在编译期完成,基本类型的自动转换在赋值、方法调用和算术运算3种情况下都会发生
规则如下:
双操作数
★如果两个操作数中有一个是double类型的,则系统先将另一个操作数的数值转换为double型的,然后再运算,否则
★如果两个操作数中有一个是float类型的,则系统先将另一个操作数的数值转换为float型的,然后再运算,否则
★如果两个操作数中有一个是long类型的,则系统先将另一个操作数的数值转换为long型的,然后再运算,否则
★两个操作数都将被转为int类型进行运算。(低于int的类型会自动提升)
★如果采用+=、*=等缩略形式的运算符,则系统会强制将运算结果转换成目标变量类型
单操作数
++、--运算对于byte、short、char类型来说不会提升数据类型到int,且运算结果类型也不变
取正(+)、取负(-)、取反(~)时,如果是byte、short、char类型,则会先被提升为int类型,再参与算术运算
如果操作数为long或int型,无论何种单目操作都不会发生类型转换,且运算结果类型不变
基本类型的造型(强制类型转换)
基本类型的造型是指程序员明确地声明,需要把取值范围宽的类型转换为取值范围窄的类型,如果没有明确使用 (类型) 造型声明,则会出现编译错误。
强制类型转换(造型)发生在运行期
注意:布尔类型数据和其他类型数据无法互相造型。
如果想转换的话可以采用条件表达式(boolean b)?1:0。
造型的结果可能引起精度的丢失
此外还要注意超过数据类型范围的造型造成的是结果的改变,如byte b = (byte)300;其最终的值是44
★JAVA中的运算
单目运算:++、--、取正+、取负-、按位取反~、逻辑取反!、造型()
其中++运算要注意:++在前,先加再赋值;++在后,先赋值再加。(--类似),取负(-)对象最好用括号括起来
算术运算:+加法、-减法、*乘法、/除法、%取模
★加法/减法:
当基本类型数据做运算时,如果+或-两边是byte、short、char时,会自动转换为int类型,其他情况取决于两个操作数中取值范围较宽的类型
注意:在JAVA中 byte b += 10是可以通过编译的,但是byte b = 10 + 10是不能通过编译的,要改为byte b = (byte)(10 + 10);
当加减运算产生的结果发生数据溢出时,不会抛出ArithmeticException.只是会出现精度丢失现象
+号的另一个功用:当加号两边至少有一个操作数为字符串时,+号起的是连接作用。例如:1+ ”a” + 2的结果是1a2;1+2+”a”的结果是3a;”a”+1+2的结果则是a12;
★乘法:
当*号两边的数据类型为char、byte、short时,其均会自动转为int类型,除此以外运算的结果取决于两个操作数中取值范围较宽的类型
当乘法运算产生的结果发生数据溢出时,不会抛出ArithmeticException.只是会出现精度丢失现象
★除法:
当/号两边的数据类型均为整型时,结果为整型(不管能否除尽)。如:7/2结果为3
当/号两边的数据有一个是浮点类型时,结果为浮点类型
如果左操作数为整型,当/号的右操作数为0时,则会抛出算术异常
如果左操作数是浮点型,当/号的右操作数为0时,不会抛出算术异常
对于浮点型数据,即使/号的右操作数为0,也不会抛出算术异常
其常见的结果有三种Infinity;-Infinity;NaN
其中NaN的情况有0.0/0、0.0/0.0、0/0.0; Infinity的情况为2.0/0; -Infinity的情况为-2.0/0
★取模:
取模运算的实质是用左操作数连续减去右操作数,直到相减的结果小于有操作数,此时的结果即为余数
当取模运算中有负数作为操作数时,取模运算结果的符号取决于左操作数的符号
如果左操作数为整型,当%号的右操作数为0时,则会抛出算术异常
如果左操作数是浮点型,当%号的右操作数为0时,不会抛出算术异常
对于浮点型数据,即使%号的右操作数为0,也不会抛出算术异常。例如:2.0%0、-2.0%0、0.0%0、0%0.0、0.0%0.0的结果均为NaN
移位运算:
JAVA中提供了三种移位运算:左移(<<) 右移(>>) 无符号右移(>>>)
移位运算的操作数只能是整型char、byte、short、int、long
左移<<:在低位补零,高位舍弃,其实质相当于 *2
右移>>: 如果值为正,则在高位补零,低位舍弃,如果值为负,则在高位补1,低位舍弃,相当于 /2
无符号右移>>>:不论正负与否高位均补零,低位舍弃
移位运算要注意:对于移动位大于该数据类型位数的时候,先取模再移位。例如:对一个int类型的数据左移33位相当于左移1位
比较运算:
JAVA中的比较运算有<小于、>大于、<=小于等于、>=大于等于、==等于、!=不等于
字符char类型可以和其他类型进行比较,因为每一个字符都对应一个标准字符码
此外还有一个特殊的比较运算符instanceof,用于在运行期检测对象的所属的类型,左操作数为一个对象引用表达式,通常为一个引用变量或数组元素,可以取值为null,返回为false,不会抛出任何异常。右操作数必须为一个类、接口、数组,但不能是java.lang.Class或者代表类名称的字符串对象
例如:下述代码均返回true
JButton[] buttons = new JButton[5];
System.out.println(buttons instanceof Object);
System.out.println(buttons instanceof Component[]);
System.out.println(buttons instanceof Object[]);
位运算:
JAVA中的位运算有按位与&、按位或|、按位异或^、按位非~
★按位与&:当两个操作数的对应位均为1时,结果为1,否则为0;
★按位或|:当两个操作数的对应为均为0时,结果为0,否则为1;
★按位异或^:当两个操作数的对应为相同时结果为0,不同时结果为1;
★按位非~:一元运算,输入为0,输出为1,输入为1,输出为0;
★除了按位非~之外其余的三种运算都可以使用布尔类型。这里有个奇怪的现象,就是使用布尔类型在进行其他三种运算时,布尔值true对应位的值为1,false对应位的值为0,
当boolean按位与时,都是true结果才为true;当boolean按位或时,都是false结果才为false;当boolean按位非时,相同为false,不同为true;
注意:位运算的对象只能为整型数据(实际上只能是int或long,其余的自动类型转换了)。布尔类型和其他基本类型数据间不能进行位运算
根据计算机中二进制正负数之间的关系,按位取反运算可以采用取负减一法,即~i = (-i)-1此种变换适于计算操作数很大的情况
逻辑运算:
JAVA中提供了&、|、&&、||、!五种逻辑运算
★&&运算符为短路运算,只要第一个值为false就不会去做后面的运算而直接将整个表达式的结果赋值为false
★||运算为短路运算,只要第一个值为true就不会去做后面的运算而直接将整个表达式的结果赋值为true
条件运算:
<boolean表达式>?表达式1:表达式2
如果boolean表达式结果为true,输出表达式1的内容,否则输出表达式2的内容,相当于一个简化版本的if…else语句
赋值运算:
JAVA中的赋值运算有=、+=、-=、*=、/=、%=、^=等,只需注意一点:左操作数必须是个变量
赋值运算的核心在于数据类型转换
★JAVA中的流程控制
顺序结构:按照语句出现的先后顺序依次执行的程序结构
分支结构:
★if……else结构,标准形式如下:
if(boolean_condition_expression){
Statement_block;
}else{
Statement_block;
}
if……else结构可以是最简单的if形式,也可以是复杂的嵌套形式if……else if……else形式
注意:在多个if存在的情况下,else和最近的一个if配对。(建议使用{})
★switch结构,标准形式如下:
switch(n){
case 0: statement;break;
case 1: statement;break;
……
default:statement;
☆n为选择因子,如果和后面的某个case匹配成功,就执行其后的语句,直到遇到break退出,如果一个case语句后没有break语句,那么意味着它会继续按顺序执行之后的每一个case语句直到遇到break退出或所有的case语句执行完毕为止
☆JAVA中n的类型只能为byte、short、char、int和Enum类型
☆case语句后与选择因子n匹配的数必须是常量
☆default语句不是必须的,其也可以放在switch结构的任意位置,一般放于尾部。按照JAVA的约定,如果switch语句中的选择因子n和所有的case均不匹配时会执行default语句,要注意的是,如果default语句不是放在整个结构的最后,那么执行完default语句后,后面的case语句还是会被执行
循环结构
JAVA中提供了三种循环结构:while、do…while、for
其中JDK5.0提供了增强的for循环,用于遍历数组和集合
while(boolean_condition_expression){
repeated_statements_block;
}
do{
repeated_statements_block;
}while(boolean_condition_expression);此处的分号要小心
对于do…while循环来说,其至少会执行一次
for(init_statement;condition_expression;span_statement){ repeated_statements_block};
for循环执行时,首先执行init_statement,然后进行条件判断,条件为true时执行repeated_statements_block,然后执行span_statement语句
之后判断条件是否满足,满足的话继续执行repeated_statements_block代码,然后再执行span_statement语句,如此循环下去,直到条件不满足停止循环
在init_statement部分可以同时初始化多个变量,其声明格式为:DataType var1 = value1,var2 = value2……(严格遵守)
注意:for(double x = 0; x != 10; x += 0.1)这样的循环是无限循环
foreach结构
for(declaration : expression)前面的声明是一个变量,其类型与数组或集合内元素的类型兼容,表达式是将要遍历的数组或集合
JAVA中使用break和continue来代替C/C++中goto的作用
★break:单独使用break语句时,表示跳出当前循环,继续执行其他语句。配合标签使用(标签的格式为Label:只能放于循环体之前)时,跳到标签位置继续执行其他语句
★continue:单独使用continue语句时,跳出外层循环起始处,从外层循环开始循环。配合标签使用时,表示调到标签之后,从标签处开始执行循环
对于for循环来说,continue语句其实直接跳到了span_statement处。(单一循环)