Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。
Java可运行于多个平台,如Windows, Mac OS,及其他多种UNIX版本的系统。
本教程通过简单的实例将让大家更好的了解JAVA编程语言。
以下我们通过一个简单的实例来展示Java编程,本实例输出"Hello World",这也是所有语言入门的第一个实例程序:
public class Main{ public static void main(String []args) { System.out.println("Hello World"); }}
Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。由詹姆斯·高斯林(James Gosling)和同事们共同研发,并在1995年正式推出。
Java分为三个体系:
2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名以取消其中的数字"2":J2EE更名为Java EE, J2SE更名为Java SE,J2ME更名为Java ME。
2009年,sun公司被oracle收购.
2018年,开源组织Eclipse基金会宣布将JavaEE(Enterprise Edition)被更名为JakartaEE(雅加达)。
Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,而是引用。并提供了自动的内存回收管理机制,使得程序员不必为内存管理而担忧。
Java语言提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定,而C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。
Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。除了Java语言具有的许多安全特性以外,Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。
Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后可以在实现这个Java平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
这种可移植性来源于体系结构中立性,另外,Java还严格规定了各个基本数据类型的长度。Java系统本身也具有很强的可移植性,Java编译器是用Java实现的,Java的运行环境是用ANSI C实现的。
如前所述,Java程序在Java平台上被编译为字节码格式,然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
与那些解释型的高级脚本语言相比,Java的确是高性能的。事实上,Java的运行速度随着JIT(Just-In-Time)编译器技术的发展越来越接近于C++。
在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为Thread(Runnable)的构造子将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
Java语言的设计目标之一是适应于动态变化的环境。Java程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
Java语言尽量保证系统内存在1G以上,其他工具如下所示:
安装好以上的工具后,我们就可以输出Java的第一个程序"Hello World!"
public class MyFirstJavaProgram { public static void main(String []args) { System.out.println("Hello World"); }}
在下一章节我们将介绍如何配置java开发环境。
在本章节中我们将为大家介绍如何搭建Java开发环境,以及不同系统下的环境变量怎么配置。
本站提供java在线运行工具:https://www.51coolma.cn/tryrun/runcode?lang=java-openjdk,但由于在线环境权限不足,大部分代码都不能直接在线运行,所以搭好一个本地可运行的环境相当重要!!!
首先我们需要下载java开发工具包JDK,下载地址:https://www.oracle.com/java/technologies/downloads/#java11-windows
点击如下下载按钮:
在下载页面中你需要选择接受许可,并根据自己的系统选择对应的版本,本文以 Window 64位系统为例:
下载后JDK的安装根据提示进行,还有安装JDK的时候也会安装JRE,一并安装就可以了。
安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为 C:Program Files (x86)Javajdk11.0.1。
1.右击“我的电脑”→“属性”→“高级系统设置”→“高级”→“环境变量”;
4. 同上,新建“CLASSPATH”系统变量,变量值为“.;%JAVA_HOME%lib;%JAVA_HOME%libdt.jar;%JAVA_HOME%lib ools.jar;”
。(引号内的全部内容,注意最前方是点不是逗号)
5. 双击“系统变量”下的“Path”变量进行编辑。(此时可以看到JAVA_HOME已经存在于系统变量中),(有的电脑"Path"也写作“PATH”)
这是 Java 的环境配置,配置完成后,你可以启动 Eclipse 来编写代码,它会自动完成java环境的配置。
在"系统变量"中设置3项属性,JAVA_HOME,PATH,CLASSPATH(大小写无所谓),若已存在则点击"编辑",不存在则点击"新建"。
变量设置参数如下:
注意:如果使用1.5以上版本的JDK,不用设置CLASSPATH环境变量,也可以正常编译和运行Java程序。
1、同时按键盘上“win”、“R”两个键打开运行,输入“cmd”确定打开控制台。
2、键入命令: java -version、java、javac 几个命令,出现以下信息,说明环境变量配置成功;
环境变量PATH应该设定为指向Java二进制文件安装的位置。如果设置遇到困难,请参考shell文档。
例如,假设你使用bash作为shell,你可以把下面的内容添加到你的 .bashrc文件结尾: export PATH=/path/to/java:$PATH
正所谓工欲善其事必先利其器,我们在开发java语言过程中同样需要一款不错的开发工具,目前市场上的IDE很多,本文为大家推荐以下几款java开发工具:
Eclipse:另一个免费开源的java IDE,下载地址: https://www.eclipse.org/eclipseide/
选择 Eclipse IDE for Java Developers:
Notepad++ : Notepad++ 是在微软windows环境之下的一个免费的代码编辑器,下载地址: http://notepad-plus-plus.org/
HelloWorld.java 文件代码:
public class HelloWorld { public static void main(String []args) { System.out.println("Hello World"); }}
一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。
下面看一个简单的 Java 程序,它将打印字符串 Hello World
public class MyFirstJavaProgram { /* 第一个Java程序. * 它将打印字符串 Hello World */ public static void main(String []args) { System.out.println("Hello World"); // 打印 Hello World }}
下面将逐步介绍如何保存、编译以及运行这个程序:
你将会在窗口看到 Hello World
C : > javac MyFirstJavaProgram.javaC : > java MyFirstJavaProgram Hello World
编写Java程序时,应注意以下几点:
public static void main(String[] args)
方法开始执行。Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
关于Java标识符,有以下几点需要注意:
像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:
在后面的章节中我们会深入讨论Java修饰符。
Java中主要有如下几种类型的变量
数组是储存在堆上的对象,可以保存多个同类型变量。在后面的章节中,我们将会学到如何声明、构造以及初始化一个数组。
Java 5.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保留字。这些保留字不能用于常量、变量、和任何标识符的名称。
关键字 | 描述 |
---|---|
abstract | 抽象方法,抽象类的修饰符 |
assert | 断言条件是否满足 |
boolean | 布尔数据类型 |
break | 跳出循环或者label代码段 |
byte | 8-bit 有符号数据类型 |
case | switch语句的一个条件 |
catch | 和try搭配捕捉异常信息 |
char | 16-bit Unicode字符数据类型 |
class | 定义类 |
const | 未使用 |
continue | 不执行循环体剩余部分 |
default | switch语句中的默认分支 |
do | 循环语句,循环体至少会执行一次 |
double | 64-bit双精度浮点数 |
else | if条件不成立时执行的分支 |
enum | 枚举类型 |
extends | 表示一个类是另一个类的子类 |
final | 表示一个值在初始化之后就不能再改变了 表示方法不能被重写,或者一个类不能有子类 |
finally | 为了完成执行的代码而设计的,主要是为了程序的健壮性和完整性,无论有没有异常发生都执行代码。 |
float | 32-bit单精度浮点数 |
for | for循环语句 |
goto | 未使用 |
if | 条件语句 |
implements | 表示一个类实现了接口 |
import | 导入类 |
instanceof | 测试一个对象是否是某个类的实例 |
int | 32位整型数 |
interface | 接口,一种抽象的类型,仅有方法和常量的定义 |
long | 64位整型数 |
native | 表示方法用非java代码实现 |
new | 分配新的类实例 |
package | 一系列相关类组成一个包 |
private | 表示私有字段,或者方法等,只能从类内部访问 |
protected | 表示字段只能通过类或者其子类访问 子类或者在同一个包内的其他类 |
public | 表示共有属性或者方法 |
return | 方法返回值 |
short | 16位数字 |
static | 表示在类级别定义,所有实例共享的 |
strictfp | 浮点数比较使用严格的规则 |
super | 表示基类 |
switch | 选择语句 |
synchronized | 表示同一时间只能由一个线程访问的代码块 |
this | 表示调用当前实例 或者调用另一个构造函数 |
throw | 抛出异常 |
throws | 定义方法可能抛出的异常 |
transient | 修饰不要序列化的字段 |
try | 表示代码块要做异常处理或者和finally配合表示是否抛出异常都执行finally中的代码 |
void | 标记方法不返回任何值 |
volatile | 标记字段可能会被多个线程同时访问,而不做同步 |
while | while循环 |
类似于C/C++,Java也支持单行以及多行注释。注释中的字符将被Java编译器忽略。
public class MyFirstJavaProgram{ /* 这是第一个Java程序 *它将打印Hello World * 这是一个多行注释的示例 */ public static void main(String []args){ // 这是单行注释的示例 /* 这个也是单行注释的示例 */ System.out.println("Hello World"); }}
空白行,或者只有注释的行,Java编译器都会忽略掉。
在Java中,一个类可以由其他类派生。如果你要创建一个类,而且已经存在一个类具有你所需要的属性或方法,那么你可以将新创建的类继承该类。
利用继承的方法,可以重用已存在类的方法和属性,而不用重写这些代码。被继承的类称为超类(super class),派生类称为子类(subclass)。
在Java中,接口可理解为对象间相互通信的协议。接口在继承中扮演着很重要的角色。
接口只定义派生要用到的方法,但是方法的具体实现完全取决于派生类。
下一节介绍Java编程中的类和对象。之后你将会对Java中的类和对象有更清楚的认识。
在理解Java的类和对象之前,先简单介绍一下面向对象的程序设计。程序设计是通过对象对程序进行设计,对象代表一个实体,实体可以清楚地被识别。
Java作为一种面向对象语言。支持以下基本概念:
本节我们重点研究对象和类的概念。
现在让我们深入了解什么是对象。看看周围真实的世界,会发现身边有很多对象,车,狗,人等等。所有这些对象都有自己的状态和行为。
拿一条狗来举例,它的状态有:名字、品种、颜色,行为有:叫、摇尾巴和跑。
对比现实对象和软件对象,它们之间十分相似。
软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。
在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。
类可以看成是创建 Java 对象的模板。
通过下面一个简单的类来理解下 Java 中类的定义:
public class Dog{ String breed; int age; String color; void barking(){ } void hungry(){ } void sleeping(){ }}
一个类可以包含以下类型变量:
一个类可以拥有多个方法,在上面的例子中: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("Puppy Name is :" + name ); } public static void main(String []args){ // 下面的语句将创建一个Puppy对象 Puppy myPuppy = new Puppy( "tommy" ); }}
编译并运行上面的程序,会打印出下面的结果:
Puppy Name is :tommy
通过已创建的对象来访问成员变量和成员方法,如下所示:
/* 实例化对象 */ObjectReference = new Constructor();/* 访问其中的变量 */ObjectReference.variableName;/* 访问类中的方法 */ObjectReference.MethodName();
下面的例子展示如何访问实例变量和调用成员方法:
public class Puppy{ int puppyAge; public Puppy(String name){ // 这个构造器仅有一个参数:name System.out.println("Passed Name is :" + name ); } public void setAge( int age ){ puppyAge = age; } public int getAge( ){ System.out.println("Puppy's age is :" + puppyAge ); return puppyAge; } public static void main(String []args){ /* 创建对象 */ Puppy myPuppy = new Puppy( "tommy" ); /* 通过方法来设定age */ myPuppy.setAge( 2 ); /* 调用另一个方法获取age */ myPuppy.getAge( ); /*你也可以像下面这样访问成员变量 */ System.out.println("Variable Value :" + myPuppy.puppyAge ); }}
编译并运行上面的程序,产生如下结果:
Passed Name is :tommyPuppy's age is :2Variable Value :2
在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import
语句和package
语句时,要特别注意这些规则。
public
类public
类public
类的类名保持一致。例如:源文件中public
类的类名是Employee
,那么源文件应该命名为Employee.java
。package
语句应该在源文件的首行。import
语句,那么应该放在package
语句和类定义之间。如果没有package
语句,那么import
语句应该在源文件中最前面。import
语句和package
语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。类有若干种访问级别,并且类也分不同的类型:抽象类和final
类等。这些将在访问控制章节介绍。
除了上面提到的几种类型,Java 还有一些特殊的类,如:内部类、匿名类。
包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。
在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。Import
语句就是用来提供一个合理的路径,使得编译器可以找到某个类。
例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类
import java.io.*;
在该例子中,我们创建两个类:Employee 和 EmployeeTest。
首先打开文本编辑器,把下面的代码粘贴进去。注意将文件保存为 Employee.java。
Employee 类有四个成员变量:name、age、designation 和 salary。该类显式声明了一个构造方法,该方法只有一个参数。
import java.io.*;public class Employee{ String name; int age; String designation; double salary; // Employee 类的构造器 public Employee(String name){ this.name = name; } // 设置age的值 public void empAge(int empAge){ age = empAge; } /* 设置designation的值*/ public void empDesignation(String empDesig){ designation = empDesig; } /* 设置salary的值*/ public void empSalary(double empSalary){ salary = empSalary; } /* 打印信息 */ public void printEmployee(){ System.out.println("Name:"+ name ); System.out.println("Age:" + age ); System.out.println("Designation:" + designation ); System.out.println("Salary:" + salary); }}
程序都是从 main
方法开始执行。为了能运行这个程序,必须包含 main
方法并且创建一个实例对象。
下面给出 EmployeeTest 类,该类实例化2个 Employee 类的实例,并调用方法设置变量的值。
将下面的代码保存在 EmployeeTest.java 文件中。
import java.io.*;public class EmployeeTest{ public static void main(String args[]){ /* 使用构造器创建两个对象 */ Employee empOne = new Employee("James Smith"); Employee empTwo = new Employee("Mary Anne"); // 调用这两个对象的成员方法 empOne.empAge(26); empOne.empDesignation("Senior Software Engineer"); empOne.empSalary(1000); empOne.printEmployee(); empTwo.empAge(21); empTwo.empDesignation("Software Engineer"); empTwo.empSalary(500); empTwo.printEmployee(); }}
编译这两个文件并且运行 EmployeeTest 类,可以看到如下结果:
C :> javac Employee.javaC :> vi EmployeeTest.javaC :> javac EmployeeTest.javaC :> java EmployeeTestName:James SmithAge:26Designation:Senior Software EngineerSalary:1000.0Name:Mary AnneAge:21Designation:Software EngineerSalary:500.0
变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。
内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。
因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。
Java的两大数据类型:
Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
byte型:
short型(短整型):
int型(整型):
long(长整型):
float(单精度浮点型):
double(双精度浮点型):
boolean(布尔型):
char(字符型):
对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。请看下面的例子:
public class PrimitiveTypeTest { public static void main(String[] args) { // byte System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE); System.out.println("包装类:java.lang.Byte"); System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE); System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE); System.out.println(); // short System.out.println("基本类型:short 二进制位数:" + Short.SIZE); System.out.println("包装类:java.lang.Short"); System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE); System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE); System.out.println(); // int System.out.println("基本类型:int 二进制位数:" + Integer.SIZE); System.out.println("包装类:java.lang.Integer"); System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE); System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE); System.out.println(); // long System.out.println("基本类型:long 二进制位数:" + Long.SIZE); System.out.println("包装类:java.lang.Long"); System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE); System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE); System.out.println(); // float System.out.println("基本类型:float 二进制位数:" + Float.SIZE); System.out.println("包装类:java.lang.Float"); System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE); System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE); System.out.println(); // double System.out.println("基本类型:double 二进制位数:" + Double.SIZE); System.out.println("包装类:java.lang.Double"); System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE); System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE); System.out.println(); // char System.out.println("基本类型:char 二进制位数:" + Character.SIZE); System.out.println("包装类:java.lang.Character"); // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台 System.out.println("最小值:Character.MIN_VALUE=" + (int) Character.MIN_VALUE); // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台 System.out.println("最大值:Character.MAX_VALUE=" + (int) Character.MAX_VALUE);}}
编译以上代码输出结果如下所示:
基本类型:byte 二进制位数:8包装类:java.lang.Byte最小值:Byte.MIN_VALUE=-128最大值:Byte.MAX_VALUE=127基本类型:short 二进制位数:16包装类:java.lang.Short最小值:Short.MIN_VALUE=-32768最大值:Short.MAX_VALUE=32767基本类型:int 二进制位数:32包装类:java.lang.Integer最小值:Integer.MIN_VALUE=-2147483648最大值:Integer.MAX_VALUE=2147483647基本类型:long 二进制位数:64包装类:java.lang.Long最小值:Long.MIN_VALUE=-9223372036854775808最大值:Long.MAX_VALUE=9223372036854775807基本类型:float 二进制位数:32包装类:java.lang.Float最小值:Float.MIN_VALUE=1.4E-45最大值:Float.MAX_VALUE=3.4028235E38基本类型:double 二进制位数:64包装类:java.lang.Double最小值:Double.MIN_VALUE=4.9E-324最大值:Double.MAX_VALUE=1.7976931348623157E308基本类型:char 二进制位数:16包装类:java.lang.Character最小值:Character.MIN_VALUE=0最大值:Character.MAX_VALUE=65535
Float和Double的最小值和最大值都是以科学记数法的形式输出的,结尾的"E+数字"表示E之前的数字要乘以10的“数字”次幂。比如3.14E3就是3.14×1000=3140,3.14E-3就是3.14/1000=0.00314。
实际上,JAVA中还存在另外一种基本类型void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。
常量就是一个固定值。它们不需要计算,直接代表相应的值。
常量指不能改变的量。 在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
lines"""This is in quotes""
字符串常量和字符常量都可以包含任何Unicode字符。例如:
char a = 'u0001';String a = "u0001";
Java语言支持一些特殊的转义字符序列。
符号 | 字符含义 |
---|---|
换行 (0x0a) | |
回车 (0x0d) | |
f | 换页符(0x0c) |
退格 (0x08) | |