Java编程基础(1)| 春松客服
目录
基本数据类型和语法
示例代码
A set of examples to learning Java. 链接:https://github.com/Samurais/java-get-started
java-get-started 示例
- 基本数据类型
- 控制流
- 异常处理
- 反射
- 切面编程
- 面向对象编程
- Java 8 新特性
1. Java简介
- Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。由James Gosling和同事们共同研发,并在1995年正式推出。
- Java演变过程
- Java Application
Java Application是完整的程序,可以独立运行,程序被编译以后,用普通的Java解释器就可以使其边解释边执行。每个Java Application程序必定含有一个并且只有一个main方法,程序执行时,首先寻找main方法,并以此为入口点开始运行。含有main方法的那个类,常被称为主类,也就是 说,Java Application程序都含有一个主类。
- JVM Architecture
Java Virtual machine (JVM)是运行Java字节码的虚拟机。您可以通过将.java文件编译为文件来获取此字节码.class。.class文件包含JVM可以理解的字节码。
在现实世界中,JVM是一种规范,提供了可以在其中执行Java字节码的运行时环境。不同的供应商提供此规范的不同实现。
- JDK, JRE和JVM
JRE = JVM +运行Java应用程序的库。
JDK = JRE +开发Java应用程序的工具。
如果您是编写代码的Java应用程序开发人员,则需要在计算机中安装JDK。但是,如果只想运行用Java内置的应用程序,则只需要在计算机上安装JRE。
2. 基础数据类型
Java基本类型共有八种,基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte、short、int、long、float、double。 数值类型又可以分为整数类型byte、short、int、long和浮点数类型float、double。
- 八种基本数据类型的默认值
序号 | 数据类型 | 大小/位 | 封装类 | 默认值(零值) | 可表示数据范围 |
---|---|---|---|---|---|
1 | byte(字节) | 8-bit | Byte | (byte)0 | -128~127 |
2 | short(短整数) | 16-bit | Short | (short)0 | -32768~32767 |
3 | int(整数) | 32-bit | Integer | 0 | -2147483648~2147483647 |
4 | long(长整数) | 64-bit | Long | 0L | -9223372036854775808 ~ 9223372036854775807 |
5 | float(单精度) | 32-bit | Float | 0.0F | 1.4E-45~3.4028235E38 |
6 | double(双精度) | 64-bit | Double | 0.0D | 4.9E-324~1.7976931348623157E308 |
7 | boolean | 它的“大小”不是精确定义的 | Boolean | flase | true或false |
8 | char(字符) | 16-bit | Character | ‘\u0000’(对应数字0,输出为空) | 0~65535 |
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’;。
3. 控制流
if…else
一个 if 语句包含一个布尔表达式和一条或多条语句。
if 语句后面可以跟 else 语句,当 if 语句的布尔表达式值为 false 时,else 语句块会被执行。
if…else 的用法如下:
if(布尔表达式){
//如果布尔表达式的值为true
}else{
//如果布尔表达式的值为false
}
使用 if…else语句的时候,需要注意下面几点:
- if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后。
- if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
- 一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行。
switch case
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
语法
switch case 语句语法格式如下:
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
switch case 语句有如下规则:
- switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
- switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
- case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
- 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
- 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
- switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
while
while是最基本的循环,它的结构为:
while( 布尔表达式 ) {
//循环内容
}
只要布尔表达式为 true,循环就会一直执行下去。
do…while
对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。
do {
//代码语句
}while(布尔表达式);
注意:布尔表达式在循环体的后面,所以语句块在检测布尔表达式之前已经执行了。 如果布尔表达式的值为 true,则语句块一直执行,直到布尔表达式的值为 false。
for
虽然所有循环结构都可以用 while 或者 do…while表示,但 Java 提供了另一种语句 —— for 循环,使一些循环结构变得更加简单。
for循环执行的次数是在执行前就确定的。语法格式如下:
for(初始化; 布尔表达式; 更新) {
//代码语句
}
关于 for 循环有以下几点说明:
- 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
- 然后,检测布尔表达式的值。如果为 true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
- 执行一次循环后,更新循环控制变量。
- 再次检测布尔表达式。循环执行上面的过程。
示例代码
package com.chatopera.tutorials.java.controlflow;
import java.util.ArrayList;
import java.util.Arrays;
public class Sample {
// 枚举类型
public enum FOO {
FOO1, FOO2;
}
public static void main(String[] args) {
// about if and equal
String a = "";
String b = new String("");
if (a == b) {
System.out.println("if: equal");
} else {
System.out.println("if: not equal");
}
FOO c = FOO.FOO1;
switch (c) {
case FOO1:
System.out.println("switch: FOO1");
break;
case FOO2:
System.out.println("switch: FOO2");
break;
default:
System.out.println("switch: Error");
}
int loop = 5;
while (loop-- > 0) {
System.out.println("while: loop" + loop);
if (loop < 3) {
break;
}
}
ArrayList<String> d = new ArrayList<>(Arrays.asList("a", "b", "c"));
for (final String e : d) {
System.out.println("for: " + e);
// continue
// break
}
}
}
代码执行结果
4. 异常处理
异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。
所有的异常类是从 java.lang.Exception 类继承的子类。
Exception 类是 Throwable 类的子类。除了Exception类外,Throwable还有一个子类Error 。
Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
Error 用来指示运行时环境发生的错误。
Java 语言定义了一些异常类在 java.lang 标准包中。
标准运行时异常类的子类是最常见的异常类。由于 java.lang 包是默认加载到所有的 Java 程序的,所以大部分从运行时异常类继承而来的异常都可以直接使用。
Java 的非检查性异常
Java 根据各个类库也定义了一些其他的异常,下面的表中列出了 Java 的非检查性异常。
异常 | 描述 |
---|---|
ArithmeticException | 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。 |
ArrayIndexOutOfBoundsException | 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。 |
ArrayStoreException | 试图将错误类型的对象存储到一个对象数组时抛出的异常。 |
ClassCastException | 当试图将对象强制转换为不是实例的子类时,抛出该异常。 |
IllegalArgumentException | 抛出的异常表明向方法传递了一个不合法或不正确的参数。 |
IllegalMonitorStateException | 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。 |
IllegalStateException | 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。 |
IllegalThreadStateException | 线程没有处于请求操作所要求的适当状态时抛出的异常。 |
IndexOutOfBoundsException | 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。 |
NegativeArraySizeException | 如果应用程序试图创建大小为负的数组,则抛出该异常。 |
NullPointerException | 当应用程序试图在需要对象的地方使用 null 时,抛出该异常 |
NumberFormatException | 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。 |
SecurityException | 由安全管理器抛出的异常,指示存在安全侵犯。 |
StringIndexOutOfBoundsException | 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。 |
UnsupportedOperationException | 当不支持请求的操作时,抛出该异常。 |
Java 的检查性异常类
下面的表中列出了 Java 定义在 java.lang 包中的检查性异常类。
异常 | 描述 |
---|---|
ClassNotFoundException | 应用程序试图加载类时,找不到相应的类,抛出该异常。 |
CloneNotSupportedException | 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。 |
IllegalAccessException | 拒绝访问一个类的时候,抛出该异常。 |
InstantiationException | 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。 |
InterruptedException | 一个线程被另一个线程中断,抛出该异常。 |
NoSuchFieldException | 请求的变量不存在 |
NoSuchMethodException | 请求的方法不存在 |
捕获异常
使用 try 和 catch 关键字可以捕获异常。
使用 try 和 catch 的语法如下所示:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}
- 示例代码
package com.chatopera.tutorials.java.exceptionhandling;
public class Sample {
public Sample() {
}
void throwException(final String msg) throws SampleException {
throw new SampleException(msg);
}
// nestted class
class SampleException extends Exception {
public SampleException(final String msg) {
super(msg);
}
}
public static void main(String[] args) {
// 自定义Exception
Sample s = new Sample();
try {
s.throwException("some error message.");
} catch (SampleException e) {
e.printStackTrace();
}
// 使用assert
try {
String a = new String("a");
String b = new String("b");
// java -ea -classpath "`pwd`" $javaClassCompiled
assert a.equals(b) : "a should equal to b.";
} catch (java.lang.AssertionError e) {
e.printStackTrace();
}
// 使用系统的Exception
if (args.length == 0) {
throw new IllegalArgumentException("no args?");
}
}
}
代码运行结果:
5. 关键字
Java关键字是电脑语言里事先定义的,有特别意义的标识符,有时又叫保留字,还有特别意义的变量。Java的关键字对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数。
- static:声明在编译时已明确
静态方法,静态变量,静态块,静态嵌套类 - final:锁定引用,类
final 关键字可以修饰类,方法和变量 - 示例代码
package com.chatopera.tutorials.java.keywords;
import java.util.ArrayList;
import java.util.Date;
public class Sample {
public final static String name = "foo";
public static String name2 = "foo";
public Sample() {
}
public void append(ArrayList<String> x) {
x.add((new Date()).toString());
x = new ArrayList<>();
x.add("ff");
x.add("a");
}
public void upper(String x) {
x = x.toUpperCase();
}
public static void main(String[] args) {
System.out.println("static final name: " + Sample.name);
Sample s = new Sample();
System.out.println("variable(s) static final name: " + s.name);
s.name2 = "bar";
System.out.println("variable(s) static final name2: " + s.name2);
String a = new String("foo2");
s.upper(a);
System.out.println("Post uppger a:" + a);
final ArrayList<String> b = new ArrayList<>();
s.append(b);
System.out.println("Final arraylist size:" + b.size());
}
}
代码运行结果
Java8新特性
- Lambda
Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中) - Function
函数式接口(Functional Interfaces)。通过在接口里面添加一个抽象方法,这些方法可以直接从接口中运行 - Optional
Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常 - 示例代码
package com.chatopera.tutorials.java.java8;
import java.util.Optional;
import java.util.function.Function;
public class Sample {
public static class Name {
private String name;
public Name(final String name) {
this.name = name;
}
public Optional<String> getName() {
return Optional.ofNullable(name);
}
}
public static class Person {
private Name name;
private int age;
private String password;
public void greetings(Function<String, String> fn) {
fn.apply("Hello, my name is " + this.getName().get().getName().get());
}
public Optional<Name> getName() {
return Optional.ofNullable(name);
}
public Optional<Integer> getAge() {
return Optional.ofNullable(age);
}
public Optional<String> getPassword() {
return Optional.ofNullable(password);
}
// normal constructors and setters
Person(final String name, final int age) {
this.name = new Name(name);
this.age = age;
}
}
public static void main(String[] args) throws InterruptedException {
// lambdas
Thread t = new Thread(() -> System.out.println("Hello."));
t.run();
// Function
Person person = new Person("john", 26);
person.greetings(s -> {
System.out.println("Apply:" + s);
return s;
});
// Optional
Optional<Person> personOptional = Optional.ofNullable(person);
personOptional.ifPresent(p -> System.out.println("personOptional getAge:" + p.getAge().get()));
// flatMap
String name = personOptional
.flatMap(Person::getName)
.flatMap(Name::getName)
.orElse("");
assert name.equals("john") : "name should be equal to john";
}
}
代码运行结果
下节预告
本次我们讲了Java的基本数据类型和语法, 下次我们将带来Java的反射和切面编程,面向对象编程,Java设计模式,将进一步的为大家讲解Java的有关知识。敬请关注。
延伸阅读
开源智能客服系统
春松客服是 Chatopera 自主研发的,Apache2.0开源协议授权的智能客服系统,春松客服会不断增强客服系统的智能化,这包括利用自然语言处理、机器学习和语音识别等技术让客服工作更有效率、客服满意度更高、成本更低。