转载请标注原文地址,谢谢!
Java 基础语法
对象和类
Java中有一个概念即“万物皆对象”,一个Java程序可以认为是一系列对象的集合,这些对象通过调用彼此的方法来协同工作。
对象 :对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
类 :类是一个模板,它描述一类对象的行为和状态。
方法 :方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
实例变量 :实例变量就是状态(属性),每个对象都有独特的实例变量。
上图中,“猫科动物”为一个类,其状态为“牙齿”、“胡须”,其行为为“吃肉”。将其实例化后为“老虎”和“狮子”。
对象
软件对象和现实对象相比十分相似。
软件对象拥有状态和行为,软件对象的状态就是属性,行为通过方法体现。
在软件开发中,方法可以用来改变对象的状态,也可用来实现对象间的相互调用。
类
类可以看成是创建Java对象的模板。
public class Dog {
String breed;
int age;
String color;
void barking() {}
void hungry() {}
void sleeping() {}
}
一个类可以包含以下类型变量:
- 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
- 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
- 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
一个类可以拥有多个方法,在上面的例子中:barking()、hungry()和sleeping()都是Dog类的方法。
构造方法
每个类都有构造方法。如果没有显式的为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
public class Puppy {
public Puppy() {}
public Puppy(String name) {
// 这个构造器仅有一个参数:name
}
}
创建对象
对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:
- 声明:声明一个对象,包括对象名称和对象类型。
- 实例化:使用关键字new来创建一个对象。
- 初始化:使用new创建对象时,会调用构造方法初始化对象。
public class Puppy {
public Puppy(String name) {
// 这个构造器仅有一个参数:name
System.out.println("小狗的名字是:" + name);
}
public static void main(String[] args) {
// 下面的语句将创建一个Puppy对象
Puppy puppy = new Puppy("tommy");
}
}
编译并运行上面的程序,会打印出下面的结果:
小狗的名字是:tommy
访问实例变量和方法
通过已创建的对象来访问成员变量和成员方法,如下所示:
/* 实例化对象 */
ObjectReference = new Constructor();
/* 访问类中的变量 */
ObjectReference.variableName;
/* 访问类中的方法 */
ObjectReference.methodName();
基本数据类型
变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来存储该类型数据。
因此,通过定义不同类型的变量,可以在内存中存储整数、小数或者字符。
Java的两大数据类型:
- 内置数据类型
- 引用数据类型
内置数据类型
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位、有符号的以二进制补码表示的整数;
- 最小值是
-2147483648(-2^31)
; - 最大值是
2147483647(2^31-1)
; - 一般的整型变量默认为int类型;
- 默认值是
0
; - 例子:int a = 100000,int b = -200000。
long:
- long数据类型是64位、有符号的以二进制补码表示的整数;
- 最小值是
-9223372036854775808(-2^63)
; - 最大值是
9223372036854775807(2^63-1)
; - 这种类型主要使用在需要比较大的整数的系统上;
- 默认值是
0L
; - 例子:long a = 100000L,long b = -200000L。"L"理论上不分大小写,但是若写成"I"容易与数字"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
(即为65535); - char数据类型可以存储任何字符;
- 例子:char letter = 'A'。
引用类型
- 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如Employee、Puppy等,变量一旦声明后,类型就不能被改变了。
- 对象、数组都是引用数据类型。
- 所有引用类型的默认值都是null。
- 一个引用变量可以用来引用任何与之兼容的类型。
- 例子:Site site = new Site("Runoob")。
常量
常量在程序运行时是不能被修改的。
在Java中使用final关键字来修饰常量,声明方式和变量类似。
虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量。
final double PI = 3.1415927;
字面量可以赋给任何内置类型的变量。例如:
byte a = 68;
char a = 'A'
byte、int、long和short都可以用十进制、16进制以及8进制的方式来表示。
当使用常量的时候,前缀0
表示8进制,而前缀0x
代表16进制,例如:
int decimal = 100;
int octal = 0144;
int hexa = 0x64;
和其他语言一样,Java的字符串常量也是包含在两个引号之间的字符序列。下面是字符串型字面量的例子:
"Hello World"
"two\nlines"
"\"This is in quotes\""
字符串常量和字符常量都可以包含任何Unicode字符。例如:
char a = '\u0001';
String a = '\u0001';
Java语言支持一些特殊的转义字符序列:
符号 | 字符含义 |
---|---|
\n | 换行(0x0a) |
\r | 回车(0x0d) |
\f | 换页符(0x0c) |
\b | 退格(0x08) |
\0 | 空字符(0x20) |
\s | 字符串 |
\t | 制表符 |
\" | 双引号 |
\' | 单引号 |
\\ | 反斜杠 |
\ddd | 八进制字符(ddd) |
\uxxxx | 16进制Unicode字符(xxxx) |
自动类型转换
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转换为同一类型,然后进行运算。
转换从低级到高级:
低 ------------------------------------> 高
byte,short,char—> int —> long—> float —> double
数据类型转换必须满足如下规则:
- 不能对boolean类型进行类型转换。
- 不能把对象类型转换成不相关类的对象。
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
-
- 转换过程可能导致溢出或损失精度,例如:
int i = 128; byte b = (byte) i;
因为byte类型是8位,最大值为127,所以当int强制转换为byte类型时,值128时就会导致溢出。
-
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:
(int) 23.7 == 23; (int) -45.89f == -45;
自动类型转换
必须满足转换前的数据类型的位数要低于转换后的数据类型,例如:short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型。
public class ZiDongLeiXingZhuan {
public static void main(String[] args) {
char c1 = 'a'; // 定义一个char类型
int i1 = c1; // char自动类型转换为int
System.out.println("char自动类型转换为int后的值等于" + i1);
char c2 = 'A'; // 定义一个char类型
int i2 = c2 + 1; // char类型和int类型计算
System.out.println("char类型和int计算后的值等于" + i2);
}
}
运行结果为:
char自动类型转为int后的值等于97
char类型和int计算后的值等于66
强制类型转换
- 条件是转换的数据类型必须是兼容的。
- 格式:(type) value type是要强制类型转换后的数据类型,实例:
public class QiangZhiZhuanHuan {
public static void main(String[] args) {
int i1 = 123;
byte b = (byte) i1; // 强制类型转换为byte
System.out.println("int强制类型转换为byte后的值等于" + b);
}
}
运行结果:
int强制类型转换为byte后的值等于123
隐含强制类型转换
- 整数的默认类型是int。
- 浮点型不存在这种情况,因为在定义float类型时必须在数字后面跟上F或者f。
变量类型
在Java语言中,所有的变量在使用前必须声明。声明变量的基本格式如下:
type identifier [ = value][, identifier [= value] ...];
格式说明:type为Java数据类型。identifier是变量名。可以使用逗号隔开来表明多个同类型变量。
以下列出了一些变量的声明实例。注意有些包含了初始化过程:
int a, b, c; // 声明三个int型整数:a、b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化 z
String s = "aab"; // 声明并初始化字符串 s
double pi = 3.14159; // 声明双精度浮点型变量 pi
char x = 'x'; // 声明变量 x 的值是字符 'x'
Java语言支持的变量类型有:
- 类变量:独立于方法之外的变量,用static修饰。
- 实例变量:独立于方法之外的变量,不过没有static修饰。
- 局部变量:类的方法中的变量。
public class Variable {
static int allClicks = 0; // 类变量
String str = "hello world"; // 实例变量
public void method() {
int i = 0; // 局部变量
}
}
局部变量
- 局部变量声明在方法、构造方法或者语句块中;
- 局部变量在方法、构造方法或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
- 访问修饰符不能用于局部变量;
- 局部变量只在声明它的方法、构造方法或者语句块中可见;
- 局部变量是在栈上分配的;
- 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用;
package com.focustech.test;
public class Test {
public void pupAge() {
// 局部变量
int age = 0;
age = age + 7;
System.out.println("小狗的年龄是:" + age);
}
public static void main(String[] args) {
Test test = new Test();
test.pupAge();
}
}
实例变量
- 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
- 当一个对象被实例化之后,每个实例变量的值就跟着确定;
- 实例变量在对象创建的时候创建,在对象呗销毁的时候销毁;
- 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
- 实例变量可以声明在使用前或者使用后;
- 访问修饰符可以修饰实例变量;
- 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见。
- 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定。
- 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObjectReference.VariableName。
import java.io.*;
public class Employee {
// 这个实例变量对子类可见
public String name;
// 私有变量,仅在该类可见
private double salary;
//在构造器中对name赋值
public Employee (String empName){
name = empName;
}
//设定salary的值
public void setSalary(double empSal){
salary = empSal;
}
// 打印信息
public void printEmp(){
System.out.println("名字 : " + name );
System.out.println("薪水 : " + salary);
}
public static void main(String[] args){
Employee empOne = new Employee("AAB");
empOne.setSalary(1000);
empOne.printEmp();
}
}
类变量(静态变量)
- 类变量也称为静态变量,在类中以static关键字声明,但必须在方法构造方法和语句块之外。
- 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
- 静态变量除了被声明为常量外很少使用。常量是指声明为public/private,final和static类型的变量。常量初始化后不可改变。
- 静态变量存储在静态存储区。静态被声明被常量。很少单独使用static声明变量。
- 静态变量在第一次被访问时创建,在程序结束时销毁。
- 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为public类型。
- 默认值和实例变量相似。数值型变量默认值是0,布尔型默认值是false,引用类型默认值是null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
- 静态变量可以通过:ClassName.VariableName的方式访问。
- 类变量被声明为public static final类型时,类变量名称一般建议使用大写字母。如果静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致。
import java.io.*;
public class Employee {
// salary是静态的私有变量
private static double salary;
// DEPARTMENT是一个常量
public static final String DEPARTMENT = "开发人员";
public static void main(String[] args) {
salary = 10000;
System.out.println(DEPARTMENT + "平均工资:" + salary);
}
}
如果其他类需要访问该变量,可以通过:Employee.DEPARTMENT。
标识符
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
关于Java标识符,有以下几点需要注意:
- 所有的标识符都应该以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始。
- 首字符之后可以是字母(A-Z或者a-z),美元符($)、下划线(_)或数字的任何字符组合。
- 关键字不能用作标识符
- 标识符是大小写敏感的
- 合法标识符举例:age、$salary、_value、__1_value
- 非法标识符举例:123abc、-salary
修饰符
Java使用修饰符来修饰类中的方法和属性,主要有两类修饰符:
- 访问控制修饰符:default、public、protected、private
- 非访问控制修饰符:final、abstract、static、synchronized
访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。
- default(缺省,什么都不写):在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private:在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)。
- public:对所有类可见。使用对象:类、接口、变量、方法。
- protected:对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)。
下表展示说明访问权限:
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
默认访问修饰符-不使用任何关键字
使用默认访问修饰符声明的变量和方法,对同一包内的类是可见的。接口里的变量都隐式声明为public static final
而接口里的方法默认情况下访问权限为public
。
String version = '1.5.1';
boolean processOrder() {
return true;
}
私有访问修饰符-private
私有访问修饰符是最严格的访问级别,所以被声明为private的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为private。
声明为私有访问类型的变量只能通过类中公共的getter方法被外部类访问。
private访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
public class Logger {
private String format;
public String getFormat() {
return this.format;
}
public void setFormat(String format) {
this.format = format;
}
}
公有访问修饰符-public
被声明为public的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的public类分布在不同的包中,则需要导入相应public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
public static void main(String[] args) {
// ...
}
受保护的访问修饰符-protected
protected需要从以下两个点来分析说明:
- 子类与基类在同一包中:被声明为protected的变量、方法和构造器能被同一包中的任何其他类访问;
- 子类与基类不在同一包中:在子类中可以访问其从基类继承而来的protected方法,而不能访问基类实例的protected方法。
访问控制和继承
- 父类中声明为public的方法在子类中也必须为public。
- 父类中声明为protected的方法在子类中要么声明为protected,要么声明为public,不能声明为private。
- 父类中声明为private的方法,不能够被继承。
非访问修饰符
为了实现一些其他的功能,Java也提供了许多非访问修饰符。
- static修饰符:用来修饰类方法和类变量。
- final修饰符:用来修饰类、方法和变量,final修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
- abstract修饰符:用来创建抽象类和抽象方法。
- synchronized和volatile修饰符:主要用于线程的编程。
static修饰符
- 静态变量:static关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。静态变量也被称为类变量。局部变量不能声明为static变量。
- 静态方法:static关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。
对类变量和方法的访问可以直接使用classname.variablename和classname.methodname的方式访问。
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
}
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; // 将输出一个错误
}
}
final方法:
类中的final方法可以被子类继承,但是不能被子类修改。
声明final方法的主要目的是防止该方法的内容被修改。
public class Test {
public final void changeName(){}
}
final类:
final类不能被继承,没有类能够继承final类的任何特性。
public final class Test {}
abstract修饰符
抽象类:
抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
一个类不能同时被abstract和final修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
抽象类可以包含抽象方法和非抽象方法。
abstract class Caravan {
private double price;
private String model;
private String year;
public abstract void goFast(); // 抽象方法
public abstract void changeColor();
}
抽象方法:
抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供。
抽象方法不能被声明成final和static。
任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
如果一个类包含若干个抽象方法,那么该类必须声明为抽象类,抽象类可以不包含抽象方法。
抽象方法的声明以分号结尾,例如:public abstract sample();
public abstract class SuperClass {
abstract void m(); // 抽象方法
}
class SubClass extends SuperClass {
// 实现抽象方法
void m() {
......
}
}
synchronized修饰符
synchronized关键字声明的方法同一时间只能被一个线程访问。synchronized修饰符可以应用于四个访问修饰符。
public synchronized void showDetails() {}
transient修饰符
序列化的对象包含被transient修饰的实例变量时,java虚拟机(JVM)跳过该特定的变量。
该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。
public transient int limit = 55; // 不会持久化
public int b; // 持久化
volatile修饰符
volatile修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
一个volatile对象引用可能是null。
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run()
{
active = true;
while (active) // 第一行
{
// 代码
}
}
public void stop()
{
active = false; // 第二行
}
}
通常情况下,在一个线程调用run()方法(在Runnable开启的线程),在另一个线程调用stop()方法。如果第一行缓冲区的active值被使用,那么在第二行的active值为false时循环不会停止。
但是以上代码使用了volatile修饰active,所以该循环会停止。
关键字
类别 | 关键字 | 说明 |
---|---|---|
访问控制 | private | 私有的 |
访问控制 | protected | 受保护的 |
访问控制 | public | 公共的 |
类、方法和变量修饰符 | abstract | 声明抽象 |
类、方法和变量修饰符 | class | 类 |
类、方法和变量修饰符 | extends | 扩充、继承 |
类、方法和变量修饰符 | final | 最终值、不可改变的 |
类、方法和变量修饰符 | implements | 实现(接口) |
类、方法和变量修饰符 | interface | 接口 |
类、方法和变量修饰符 | native | 本地,原生方法(非Java实现) |
类、方法和变量修饰符 | new | 新,创建 |
类、方法和变量修饰符 | static | 静态 |
类、方法和变量修饰符 | strictfp | 严格、精准 |
类、方法和变量修饰符 | synchronized | 线程、同步 |
类、方法和变量修饰符 | transient | 短暂 |
类、方法和变量修饰符 | volatile | 易失 |
程序控制语句 | break | 跳出循环 |
程序控制语句 | case | 定义一个值以供switch选择 |
程序控制语句 | continue | 继续 |
程序控制语句 | default | 默认 |
程序控制语句 | do | 运行 |
程序控制语句 | else | 否则 |
程序控制语句 | for | 循环 |
程序控制语句 | if | 如果 |
程序控制语句 | instanceof | 实例 |
程序控制语句 | return | 返回 |
程序控制语句 | switch | 根据值选择执行 |
程序控制语句 | while | 循环 |
错误处理 | assert | 断言表达式是否为真 |
错误处理 | catch | 捕捉异常 |
错误处理 | finally | 有没有异常都执行 |
错误处理 | throw | 抛出一个异常对象 |
错误处理 | throws | 声明一个异常可能被抛出 |
错误处理 | try | 捕获异常 |
包相关 | import | 引入 |
包相关 | package | 包 |
基本类型 | boolean | 布尔型 |
基本类型 | byte | 字节型 |
基本类型 | char | 字符型 |
基本类型 | double | 双精度浮点 |
基本类型 | float | 单精度浮点 |
基本类型 | int | 整型 |
基本类型 | long | 长整型 |
基本类型 | short | 短整型 |
变量引用 | super | 父类、超类 |
变量引用 | this | 本类 |
变量引用 | void | 无返回值 |
保留关键字 | goto | 是关键字,但不能使用 |
保留关键字 | const | 是关键字,但不能使用 |
保留关键字 | null | 空 |
枚举
Java5.0引入了枚举,枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的bug。
例如,我们为果汁店设计了一个程序,它将限制果汁为小杯、中杯、大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。
class FreshJuice {
enum FreshJuiceSize {
SMALL,
MEDIUM,
LARGE
}
FreshJuiceSize size;
}
public class FreshJuiceTest {
public static void main(String[] args) {
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM;
}
}
注意:枚举可以单独声明或者声明在类里面。方法、变量、构造函数也可以在枚举中定义。
运算符
Java中的运算符分为以下几组:
- 算术运算符
- 关系运算符
- 位运算符
- 逻辑运算符
- 赋值运算符
- 其他运算符
算术运算符
算术运算符用在数学表达式中,它们的作用和在数学中的作用一样。下表列出了所有的算术运算符。
表格中的实例假设整数变量A的值为10,变量B的值为20:
操作符 | 描述 | 例子 |
---|---|---|
+ | 加法:相加运算符两侧的值 | A+B=30 |
- | 减法:左操作数减去右操作数 | A-B=-10 |
* | 乘法:相乘操作符两侧的值 | A*B=200 |
/ | 除法:左操作数除以右操作数 | B/A=2 |
% | 取余:左操作数除以右操作数的余数 | B%A=0 |
++ | 自增:操作数的值增加1 | B++或++B=21 |
-- | 自减:操作数的值减少1 | B--或--B=19 |
自增自减运算符
1、自增(++)和自减(--)运算符是一种特殊的算术运算符。在算术运算符中需要两个操作数来进行运算,而自增自减运算符只需要一个操作数。
2、前缀自增自减法(++a, --a):先进行自增或者自减运算,再进行表达式运算。
3、后缀自增自减法(a++, a--):先进行表达式运算,再进行自增或者自减运算。
关系运算符
下表为Java支持的关系运算符
表格中的实例整数变量A的值为10,变量B的值为20:
运算符 | 描述 | 例子 |
---|---|---|
== | 检查如果两个操作数的值是否相等,如果相等则条件为真。 | (A==B)为假 |
!= | 检查如果两个操作数的值是否相等,如果值不相等则条件为真。 | (A!=B)为真 |
> | 检查左操作数的值是否大于右操作数的值,如果是那么条件为真。 | (A>B)为假 |
< | 检查左操作数的值是否小于右操作数的值,如果是那么条件为真。 | (A<B)为真 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是那么条件为真。 | (A>=B)为假 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是那么条件为真。 | (A<=B)为真 |
位运算符
Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char)和字节型(byte)等类型。
位运算符作用在所有的位上,并且按位运算。假设a=60,b=13;它们的二进制格式表示将如下:
A = 0011 1100
B = 0000 1101
-----------------
A&b = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011
下表列出了位运算符的基本运算,假设整数变量A的值为60和变量B的值为13:
操作符 | 描述 | 例子 |
---|---|---|
& | 如果相对应位都是1,则结果为1,否则为0 | (A&B),得到12,即00001100 |
| | 如果相对应位都是0,则结果为0,否则为1 | (A|B),得到61,即00111101 |
^ | 如果相对应位值相同,则结果为0,否则为1 | (A^B),得到49,即00110001 |
~ | 按位取反运算符翻转操作数的每一位,即0变成1,1变成0 | (~A),得到-61,即11000011 |
<< | 按位左移运算符,左操作数按位左移右操作数指定的位数 | A<<2,得到240,即11110000 |
>> | 按位右移运算符,左操作数按位右移右操作数指定的位数 | A>>2,得到15,即00001111 |
>>> | 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充 | A>>>2,得到15,即00001111 |
逻辑运算符
下表列出了逻辑运算符的基本运算,假设布尔变量A为真,变量B为假:
操作符 | 描述 | 例子 |
---|---|---|
&& | 当且仅当两个操作数都为真,条件才为真。 | (A&&B)为假 |
|| | 如果任何两个操作数任何一个为真,条件为真。 | (A||B)为真 |
! | 用来反转操作数的逻辑状态,如果条件为true,则逻辑非运算符将得到false | !(A&&B)为真 |
短路逻辑运算符
当使用与逻辑运算符时,在两个操作数都为true时,结果才为true,但是当得到第一个操作为false时,其结果就必定是false,这时候就不会再判断第二个操作了。
public class LuoJi {
public static void main(String[] args) {
int a = 5;// 定义一个变量
boolean b = (a<4)&&(a++<10);
System.out.println("使用短路逻辑运算符的结果为"+b);
System.out.println("a的结果为"+a);
}
}
运行结果为:
使用短路逻辑运算符的结果为false
a的结果为5
解析:改程序使用了短路逻辑运算符(&&),首先判断a<4的结果为false,则b的结果必定是false,所以不再执行第二个操作a++<10的判断,所以a的值为5。
赋值运算符
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左操作数 | C=A+B,将把A+B得到的值赋给C |
+= | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C+=A等价于C=C+A |
-= | 减和赋值操作符,它把左操作数和右操作数想减赋值给左操作数 | C-=A等价于C=C-A |
*= | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C*=A等价于C=C*A |
/= | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C/=A等价于C=C/A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%=A等价于C=C%A |
<<= | 左移位赋值运算符 | C<<=2等价于C=C<<2 |
>>= | 右移位赋值运算符 | C>>=等价于C=C>>2 |
&= | 按位与赋值运算符 | C&=2等价于C=C&2 |
^= | 按位异或赋值操作符 | C=2等价于C=C2 |
|= | 按位或赋值操作符 | C|=2等价于C=C|2 |
条件运算符(?:)
条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符主要决定哪个值应该赋值给变量。
variable x = (expression) ? value if true : value if false
instanceof运算符
该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
instanceof运算符使用格式如下:
(Object reference variable) instanceof (class/interface type)
如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。
下面是一个例子:
String name = "James";
boolean result = name instanceof String; // 由于name是String类型,所以返回真
如果被比较的对象兼容于右侧类型,该运算符仍然返回true。
Java运算符优先级
下表根据优先级从高到低的顺序排序:
类别 | 操作符 | 关联性 |
---|---|---|
后缀 | () [] .(点操作符) | 左到右 |
一元 | ++ -- ! ~ | 从右到左 |
乘性 | * / % | 左到右 |
加性 | + - | 左到右 |
移位 | >> >>> << | 左到右 |
关系 | > >= < <= | 左到右 |
相等 | == != | 左到右 |
按位与 | & | 左到右 |
按位异或 | ^ | 左到右 |
按位或 | | | 左到右 |
逻辑与 | && | 左到右 |
逻辑或 | || | 左到右 |
条件 | ? : | 从右到左 |
赋值 | = += -= *= /= %= >>= <<= &= ^ = |= | 从右到左 |
逗号 | , | 左到右 |
循环结构
Java中有三种主要的循环结构:
- while循环
- do...while循环
- for循环
在Java5中引入了一种主要用于数组的增强型for循环。
while循环
while是最基本的循环,它的结构为:
while(布尔表达式) {
// 循环内容
}
只要布尔表达式为true,循环就会一直执行下去。
do...while循环
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do...while循环和while循环相似,不同的是,do...while循环至少会执行一次。
do {
// 代码语句
}while(布尔表达式);
for循环
虽然所有循环结构都可以用while或者do...while表示,但Java提供了另一种语句——for循环,使一些循环结构变得更加简单。
for循环执行的次数是在执行前就确定的。语句格式如下:
for(初始化; 布尔表达式; 更新) {
// 代码语句
}
关于for循环有以下几点说明:
- 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
- 然后,检测布尔表达式的值。如果为true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
- 执行一次循环后,更新循环控制变量。
- 再次检测布尔表达式,循环执行上面的过程。
Java增强for循环
Java5引入了一种主要用于数组的增强型for循环。
Java增强for循环语法格式如下:
for(声明语句 : 表达式) {
// 代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
break关键字
break主要用在循环语句或者switch语句中,用来跳出整个语句块。
break跳出最里面的循环,并且继续执行该循环下面的语句。
continue关键字
continue适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。
在for循环中,continue语句使程序立即跳转到更新语句。
在while或者do...while循环中,程序立即跳转到布尔表达式的判断语句。
条件语句
if...else语句
if语句后面可以跟else语句,当if语句的布尔表达值为false时,else语句块会被执行。
if(布尔表达式) {
// 如果布尔表达式的值为true
} else {
// 如果布尔表达式的值为false
}
if...else if...else语句
if语句后面可以跟else if...else语句,这种语句可以检测到多种可能的情况。
使用if,else if,else语句的时候,需要注意下面几点:
- if语句至多有1个else语句,else语句在所有的else if语句之后。
- if语句可以有若干个else if语句,它们必须在else语句之前。
- 一旦其中一个else if语句检测为true,其它的else if以及else语句都将跳过执行。
if(布尔表达式1) {
// 如果布尔表达式1的值为true,执行代码
}else if(布尔表达式2) {
// 如果布尔表达式2的值为true,执行代码
}else if(布尔表达式3) {
// 如果布尔表达式3的值为true,执行代码
}else {
// 如果以上布尔表达式都不为true,执行代码
}
嵌套的if...else语句
使用嵌套的if...else语句是合法的。也就是说你可以在另一个if或者else if语句中使用if或者else if语句。
嵌套的if...else语法格式如下:
if(布尔表达式1) {
// 如果布尔表达式1的值为true,执行代码
if(布尔表达式2) {
// 如果布尔表达式2的值为true,执行代码
}
}
String
字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串。
创建字符串
String greeting = "测试字符串"; // 使用字符串常量创建字符串
char[] array = {'a', 'b', 'c'};
String greeting = new String(array); // 使用关键字创建字符串
注意:String类是不可改变的,所以一旦创建了String对象,那它的值就无法改变了。
字符串长度
String site = "www.what's the hell.com";
int len = site.length();
连接字符串
String类提供了两种连接字符串的方法:
"我的名字是:".concat("abc"); // 使用concat方法连接
"我的名字是" + "abc"; // 使用'+'连接
创建格式化字符串
String类使用静态方法format()创建可复用的格式化字符串:
System.out.printf("浮点型变量的值为" + "%f,整型变量的值为" + "%d,字符串变量的值为" + "is %s", floatVar, intVar, stringVar);
还有更多的String的api请大家查看java的官方文档。
日期时间
java.util包提供Date类来封装当前的日期和时间,Date类提供两个构造函数来实例化Date对象。
第一个构造函数使用当前日期和时间来初始化对象:
Date()
第二个构造函数接收一个参数,该参数是1970年1月1日起的毫秒数:
Date(long millisec)
获取当前日期时间
Date date = new Date();
日期比较
Java使用以下三种方法来比较两个日期:
- 使用getTime()方法获取两个日期,然后比较这两个值。
- 使用方法before(),after()和equals()。例如,一个月的12号比18号早,则new Date(99, 2, 12).before(new Date(99, 2, 18))返回true。
- 使用compareTo()方法,它是由Comparable接口定义的,Date类实现了这个接口。
使用SimpleDateFormat格式化日期
SimpleDateFormat是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat允许你选择任何用户自定义日期时间格式来运行:
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar类
Calendar类的功能比Date类要强大很多,而且在实现方式上也比Date类要复杂一些。
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
创建一个代表系统当前日期的Calendar对象
Calendar c = Calendar.getInstance(); // 默认是当前日期
创建一个指定日期的Calendar对象
使用Calendar代表特定的时间,需要首先创建一个Calendar对象,然后再设定该对象中的年月日参数来完成。
// 创建一个代表2009年6月12日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);
Calendar类对象字段类型
常量 | 描述 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份 |
Calendar.DATE | 日期 |
Calendar.DAY_OF_MONTH | 日期,和上面的字段意义完全相同 |
Calendar.HOUR | 12小时制的小时 |
Calendar.HOUR_OF_DAY | 24小时制的小时 |
Calendar.MINUTE | 分钟 |
Calendar.SECOND | 秒 |
Calendar.DAY_OF_WEEK | 星期几 |
编程习惯
- package的命名:由小写字母组成,为防止冲突建议设置为公司域名+项目名称,例如:com.foucstech.demo。
- class和interface的命名:由大写字母开头,后面的单词用大写字母开头,例如:Person、RuntimeException。
- class变量的命名:由小写字母开头,后面的单词用大写字母开头,例如:index、currImg。
- class方法的命名:与变量的命名一致。
- class常量的命名:由大写字母组成,并且这些字母能够表达完整含义,例如:PI、PASSWORD。