Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。
主要特性
- Java 语言是简单的:
Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。
- Java 语言是面向对象的:
Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
- Java语言是分布式的:
Java 语言支持 Internet 应用的开发,在基本的 Java 应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括 URL、URLConnection、Socket、ServerSocket 等。Java 的 RMI(远程方法激活)机制也是开发分布式应用的重要手段。
- Java 语言是健壮的:
Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。
- Java语言是安全的:
Java通常被用在网络环境中,为此,Java 提供了一个安全机制以防恶意代码的攻击。除了Java 语言具有的许多安全特性以外,Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。
- Java 语言是体系结构中立的:
Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构中立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
- Java 语言是可移植的:
这种可移植性来源于体系结构中立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。
- Java 语言是解释型的:
如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
- Java 是高性能的:
与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。
- Java 语言是多线程的:
在 Java 语言中,线程是一种特殊的对象,它必须由 Thread 类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为 Thread(Runnable) 的构造子类将一个实现了 Runnable 接口的对象包装成一个线程,其二,从 Thread 类派生出子类并重写 run 方法,使用该子类创建的对象即为线程。值得注意的是 Thread 类已经实现了 Runnable 接口,因此,任何一个线程均有它的 run 方法,而 run 方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java 语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为 synchronized)。
- Java 语言是动态的:
Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
发展历史
- 1995 年 5 月 23 日,Java 语言诞生
- 1996 年 1 月,第一个 JDK-JDK1.0 诞生
- 1996 年 4 月,10 个最主要的操作系统供应商申明将在其产品中嵌入 JAVA 技术
- 1996 年 9 月,约 8.3 万个网页应用了 JAVA 技术来制作
- 1997 年 2 月 18 日,JDK1.1 发布
- 1997 年 4 月 2 日,JavaOne 会议召开,参与者逾一万人,创当时全球同类会议规模之纪录
- 1997 年 9 月,JavaDeveloperConnection 社区成员超过十万
- 1998 年 2 月,JDK1.1 被下载超过 2,000,000次
- 1998 年 12 月 8 日,JAVA2 企业平台 J2EE 发布
- 1999 年 6月,SUN 公司发布 Java 的三个版本:标准版(JavaSE, 以前是 J2SE)、企业版(JavaEE 以前是 J2EE)和微型版(JavaME,以前是 J2ME)
- 2000 年 5 月 8 日,JDK1.3 发布
- 2000 年 5 月 29 日,JDK1.4 发布
- 2001 年 6 月 5 日,NOKIA 宣布,到 2003 年将出售 1 亿部支持 Java 的手机
- 2001 年 9 月 24 日,J2EE1.3 发布
- 2002 年 2 月 26 日,J2SE1.4 发布,自此 Java 的计算能力有了大幅提升
- 2004 年 9 月 30 日 18:00PM,J2SE1.5 发布,成为 Java 语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5 更名为 Java SE 5.0
- 2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 "2":J2EE 更名为 Java EE,J2SE 更名为 Java SE,J2ME 更名为 Java ME
- 2006 年 12 月,SUN 公司发布 JRE6.0
- 2009 年 04 月 20 日,甲骨文 74 亿美元收购 Sun,取得 Java 的版权。
- 2010 年 11 月,由于甲骨文对于 Java 社区的不友善,因此 Apache 扬言将退出 JCP。
- 2011 年 7 月 28 日,甲骨文发布 Java7.0 的正式版。
- 2014 年 3 月 18 日,Oracle 公司发表 Java SE 8。
- 2017 年 9 月 21 日,Oracle 公司发表 Java SE 9
- 2018 年 3 月 21 日,Oracle 公司发表 Java SE 10
- 2018 年 9 月 25 日,Java SE 11 发布
- 2019 年 3 月 20 日,Java SE 12 发布
java三大版本:
J2SE: Standard Edition(标准版),包括那些构成Java语言核心的类。 比如;接口定义、输入/输出、网络编程、数据库连接 J2EE :Enterprise Edition(企业版),J2EE 包含J2SE中的类,并且还包括用于开发企业级应用的类. 比如:servlet、JSP、XML、事物控制 J2ME: Micro Edition(微缩版),包含J2SE中一部分类,用于消费类电子产品的软件开发。 比如:智能卡、手机、呼机
2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6
同时 Java 的各种版本已经更名以取消其中的数字 "2"
J2EE 更名为 Java EE J2SE 更名为 Java SE J2ME 更名为 Java ME
java跨平台原理
平台就是指我们计算机的操作系统,例如:Windows、Linux、Mac等操作系统。 跨平台的意思就是java程序在编译完成之后,在这些平台上都可以运行,比如我在Windows上编译好一个java程序,不做任何修改就能在Linux或者Mac系统上运行。(也就是一次编译,到处运行)
那么跨平台是如何实现的呢? 这里就要提到java虚拟机(Java Virtual Machine,简称 JVM),
- JVM是一个软件,在每个平台都有不同的版本,
- java代码被编译后生成后缀为.class的文件,叫做字节码文件,
- JVM负责将字节码文件翻译成对应平台下的机器码然后运行,
- 它的跨平台要点是实现能运行在各个平台上的JVM
简单理解:就是我们去国外旅游,每去一个不同的国家就要带上一个不同的翻译,这个翻译就是JVM,我们相当于.java文件,我们说出的中文就是.class文件,我们带的翻译肯定能听懂我们说的话,我们将我们(.java)的想法用中文(.class)说给翻译(JVM)听,然后翻译(JVM)再将我们说的话(.class)翻译给当地人(平台)听。
JVM、JDK、JRE
JVM JVM是Java Virtual Machine(Java虚拟机)的缩写, 它是整个Java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
JRE JRE是java runtime environment(java运行环境)的缩写。JRE是指java运行环境。 jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。 光有JVM还不能成class的 执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。 (jre里有运行.class的java.exe)
JDK是java development kit(java开发工具包)的缩写. 在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行 java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包含JVM。
bin: 最主要的是编译器(javac.exe) include: java和JVM交互用的头文件 lib:类库 jre: java运行环境 (注意:这里的bin、lib文件夹和jre里的bin、lib是不同的)
总的来说JDK是用于java程序的开发,而jre则是只能运行class而没有编译的功能。
JDK,JRE,JVM三者关系概括如下: jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。 JRE是JAVA程序运行时需要的运行环境, JVM内部包含许多应用程序的类的解释器和类加载器等等。 就是说如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了。JDk、JRE内部都包含JAVA虚拟机JVM,
注释
标识符
定义:java 中标识符是为方法、变量或其他用户定义项所定义的名称。
java标识符命名规则
- 应该以字母、美元符号($)、或者下划线(_)开始。
- 首字符之后可以是字母、美元符、下划线、或者数字的任何字符组合。
- 区分大小写
- 不能用关键字作为变量名或者方法名。
- 合法标识符举例:age、$salary、_value.
- 可以使用中文命名,但是不建议!
java标识符命名规范
都要遵循见名知意。
类名、接口名:首字母都要求大写,驼峰原则,形式:WwwYyyZzz
变量名、方法名:从第二个单词开始,首字母大写,驼峰原则,形式:xxxYyyZzz
包名要求字母都小写,单词以.隔开,形式:xxx.yyy.zzz
Java项目名要求字母小写。
常量名,要求所有字母大写,以_隔开,形式:XXX_YYY_ZZZ
Java 关键字
这些关键字不能作为变量名、类名和方法名来使用。以下对这些关键字进行了分类。
关键字 | |
---|---|
数据类型 | boolean、int、long、short、byte、float、double、char、class、interface、enum、void |
流程控制 | if、else、do、while、for、switch、case、default、break、continue、return |
异常处理 | try、catch、finally、throw、throws |
修饰符 | public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native |
类与类之间关系 | extends、implements |
建立实例及引用实例 | this、supper、instanceof、new |
导包 | package、impor |
字节
位(bit):是计算机内部数据存储的最小单位,11001100是一个八位二进制的数。 字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示。
1bit表示1位
1B=8b; 1KB=8B; 1M= 1024KB; 1G=1024M; 1TB=1024G;
数据类型
数据类型分为强类型语言(严格符合规定,先定义后使用)和弱类型语言(和强的相反)
Java是强类型语言
Java数据类型分为基本数据类型和引用数据类型
Java八大基本数据类型
boolean的占用内存有好几种说法,我就不做讨论了,boolean默认为false;
引用数据类型
类、接口、数组。
数据类型的转换
自动类型转换(隐式类型转换) ---------小转大
- 小的类型自动转化为大的类型
- 整数类型可以自动转化为浮点类型,可能会产生舍入误差
- 字符可以自动提升为整数
强制类型转换(显式类型转换)---------大转小
格式: 目标数据类型 变量名 = (目标数据类型)(表达式或变量);
- 强制类型转换可能导致溢出或损失精度
- 在把容量大的类型转换为容量小的类型时必须使用强制类型转换
- 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
运算符
额外: 二进制和十进制的相互转换
125转换成二进制后是1111101 100转换成二进制后是1100100 99转换成二进制后是1100011
算术运算符
操作符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 —— 左操作数除以右操作数的余数 |
++ | 自增: 操作数的值增加1 |
-- | 自减: 操作数的值减少1 |
i++和++i区别 i++,先赋值后加1 ++i,先加1后赋值
关系运算符
运算符 | 描述 |
---|---|
== | 等于 |
!= | 不等于 |
大于 | |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
位运算符
A = 0011 1100 60
B = 0000 1101 13
A&B = 0000 1100 12
A|B = 0011 1101 61
A^B = 0011 0001 49
~A = 1100 0011 -61
逻辑运算符
赋值运算符
条件运算符(?:)
条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。
variable x = (expression) ? value if true : value if false
运算符执行顺序
括号里面的优先执行,然后就是如下:
修饰符
权限访问修饰符
private(私有的)自己专属:意味着被声明的成员或方法,除了本类,其他任何类都无法访问。
default(默认的)包访问权限:即不写任何关键字,就意味着相同包内的其他类(包括子类)可以访问,包外都不可以访问。
protected(受保护的)继承访问权限:使用protected关键字,就意味着被声明的成员或方法,在子类以及相同包内的其他类都可以访问的。
public(公共的)接口访问权限:使用public关键字,就意味着被声明的成员或方法对所有类都是可以访问的。
private(私有的)自己专属
声明为private的方法,变量和构造函数只能在声明的类本身中访问 类和接口不能声明为:private。
如果类中存在公共getter方法,则可以在类中将变量声明为private。使用private修饰符是对象封装自身并隐藏来自外部世界的数据的主要方式(即私有变量,公共方法)
default(默认的)包访问权限
接口中的字段隐式为public static final,接口中的方法默认为public。
protected(受保护的)继承访问权限
受保护的访问修饰符不能应用于类和接口。 方法,字段可以声明为protected,但是接口中的方法和字段不能声明为protected。受保护的访问使子类有机会使用辅助方法或变量,同时防止非相关类尝试使用它。
public(公共的)接口访问权限
如果尝试访问的公共类位于不同的包中,则仍需要导入公共类。 由于类继承,类的所有公共方法和变量都由其子类继承。
应用程序的main()方法必须声明为public。否则Java解释器无法调用它来运行该类。
访问控制和继承
强制执行以下继承方法规则 :
- 在超类中声明为public的方法也必须在所有子类中都是public。
- 在超类中声明为protected的方法必须在子类中也要声明为:protected或public; 不能声明为private。
- 声明为private的方法根本不能被继承,因此没有规则。
额外:
一、为什么不能用private修饰Java外部类?
因为如果使用private修饰Java外部类,那么这个类不能创建实例,这个类的属性和方法不能被访问,那么创建这个类毫无意义,所以不能使用private修饰Java外部类。
二、为什么不能用protected修饰Java外部类?
举个例子,如果类A用protected修饰,与类A不同包的类B想要访问类A的话,类B就必须是继承类A的(或者说类B必须为类A的子类),但是类B继承类A的前提又是类B可以访问到类A,有点绕对吧,仔细想想会发现这里是冲突的,其实这就说明了为什么不能用protected来修饰外部类。再说,protected是用来表示在继承关系中的访问权限的,在同一个包和子类中都可以访问,因为继承就是为了拥有父类的属性和方法,所以protected是用于修饰类的方法和属性的,也就是说,我想要这个类的属性和方法可以被任何子类继承,我就用protected。
非访问修饰符
- static修饰符用于创建类方法和变量。
- final修饰符用于完成类,方法和变量的实现。
- abstract修饰符用于创建抽象类和方法。
- synchronized和volatile修饰符,用于线程。
static修饰符
由 static 关键字修饰的成员变量、成员常量、成员方法和内部类被称为静态成员变量、静态成员常量、静态成员方法和静态内部类。局部变量不能声明为static。
非静态的成员方法 和 静态的成员方法的区别
final修饰符
- final 关键字修饰基本数据类型时,其数值不能发生改变。
- final 关键字修饰引用数据类型时,其地址不能发生改变。
- final 关键字修饰成员方法时,表示该方法不能被重写。
- final 关键字修饰 class 类时,表示该类不能被继承。
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方法的主要目的是不让其它人改变方法的内容。
使用声明为final的类的主要目的是防止类被子类化。 如果一个类被标记为final,那么这个类不能被其它类继承。
abstract饰符
抽象(abstract)类不能实例化。如果一个类声明为抽象(abstract),那么唯一的目的是扩展该类。 一个类不能是同时是abstract和final(因为final类不能被扩展)。 如果一个类包含抽象方法,那么该类应该被声明为abstract。 否则,将抛出编译错误。 抽象类可以包含抽象方法以及普通方法。
抽象方法是在没有任何实现的情况下声明的方法。 方法体(实现)由子类提供。 抽象方法永远不会是最终的或严格的。 扩展抽象类的任何类都必须实现超类的所有抽象方法,除非子类也是抽象类,那就子子类实现。
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,所以该循环会停止。
变量
变量是什么?简而言之,就是可以变化的量。
type varname [ = value][, varname [ = value] ...] ; 数据类型 变量名字 = 变量值。
变量的三要素: 1.数据类型 : 决定在内存中分配的空间 2.变量名 : 空间别名 3.值 :空间中存储的数据
注意点
- 每个变量在使用前都必须声明其类型,并且声明都必须是分号结束。(Java是强类型语言, 要求变量中存储的数据类型 必须和变量声明的类型要保持一致.)。
- 变量类型可以是基本类型。也可以是引用类型。
- 变量名必须是合法的标识符。
预热图:
成员变量
作用范围是整个类,相当于C中的全局变量,定义在方法体和语句块之外,一般定义在类的声明之下;成员变量包括实例变量和静态变量(类变量);
实例变量
独立于与方法之外的变量,无static修饰,声明在一个类中,但在方法、构造方法和语句块之外,数值型变量默认值为0,布尔型默认值为false,引用类型默认值为null;
类/静态变量
独立于方法之外的变量,用static修饰,默认值与实例变量相似,一个类中只有一份,属于对象共有,存储在静态存储区,经常被声明为常量,调用一般是类名.静态变量名,也可以用对象名.静态变量名调用;
静态变量(类变量)&实例变量区别:
A:调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。这个变量属于类。
实例变量,只能通过对象名调用。这个变量属于对象。
B:存储位置
静态变量存储在方法区长中的静态区。
实例变量存储在堆内存。
C:生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
实例变量随着对象的创建而存在,随着对象的消失而消失。
D:与对象的相关性
静态变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果.
实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
public class SE004_LeiBianLiangAndShiLiBianLiang {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
}
}
class Demo{
static int i = 1; //类变量(静态变量)
int j = 1; //实例变量
public Demo(){
i++;
j++;
System.out.println(i+":"+j);
}
}
运行结果
2:2
3:2
局部变量
类的方法中的变量,声明在方法、构造方法或语句块中,在栈上分配,无默认值,必须经初始化.访问修饰符不能用于局部变量,
package com.cunyu.demo
public class Demo {
private String name; //成员变量、实例变量
private int age; //成员变量、实例变量
private int ID; //成员变量、实例变量
public static final String school = "卡塞尔学院"; //成员变量、静态变量(类变量)
public static String level = "SSS"; //成员变量、静态变量(类变量)
public int getAge() {
return age;
}
public int getId() {
return ID;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int ID) {
this.ID = ID;
}
public void setName(String name) {
this.name = name;
}
public void study(){
String subject1 = "屠龙"; //局部变量
String subject2 = "炼金术"; //局部变量
System.out.println("学习科目: " + subject1 + "、" + subject2);
}
public static void main(String[] args) {
Demo demo = new Demo();
demo.setAge(23);
demo.setId(14000001);
demo.setName("楚子航");
System.out.println("ID: " + demo.getId() + "Age: " + demo.getAge() + "Name: " + demo.getName());
System.out.print("主修科目: ");
demo.study();
System.out.println("学院:" + Demo.school);
System.out.println("等级:" + Demo.level);
}
}
实例变量&局部变量区别:
1)作用域
实例变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
(2)存储位置
实例变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。
(3)初始值
实例变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
常量
常量:初始化后不能再改变的值。也就是不会变动的值。 常量名一般使用大写字符 语法:final 常量名 = 值;如:final String LOVE = ‘java‘;
包
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间。 包语句的语法格式为:package pk1.pk2[.pk3[.pk4]]; 一般利用公司域名倒置作为包名:www.baidu.com --> com.baidu.www
为了使用某一个包的成员,需要在Java中导入包 语法: import 包名;
javaDoc
Javadoc用于描述类或者方法的作用。Javadoc可以写在类上面和方法上面。
常用标签
@author 标识一个类的作者 @version 指定类的版本 @deprecated 指名一个过期的类或成员 @throws 抛出异常 @param 参数情况 @return 返回值
用idea生成JavaDoc文档。点击前往