快速浏览
Sun公司在1991成立了一个名为Green的小组,这个小组开发了Oak,这正是java的前身,最初的开发目的是为了做家电的嵌入式应用,不过因为缺乏硬件市场的支持并没有受到大的关注。
1995的时候,互联网开始崛起,这给了java机会。Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet,并将Oak更名为Java。
1996年1月,Sun公司发布了Java的第一个开发工具包,这个工具包被命名为JDK1.0,这标志着Java正式成为了一种独立的开发工具。
1998年12月8日,第二代Java平台的企业版J2EE发布。
1999年6月,Sun公司发布了第二代Java平台的第3个版本:J2ME。
1999年4月27日,HotSpot虚拟机发布。HotSpot虚拟机发布时是作为JDK 1.2的附加程序提供的,后来它成为了JDK 1.3及之后所有版本的Sun JDK的默认虚拟机 。
2000年5月,JDK1.3、JDK1.4和J2SE1.3相继发布,几周后其获得了Apple公司Mac OS X的工业标准的支持。
2002年2月26日,J2SE1.4发布。自此Java的计算能力有了大幅提升,与J2SE1.3相比,其多了近62%的类和接口,其中比较重要的更新有XML、Socket、正则表达式改进的I/O等。
2004年9月30日,J2SE1.5发布。为了表示该版本的重要性,J2SE 1.5更名为Java SE 5.0。更新中包含了从1996年发布1.0版本以来的最重大的更新,其中包括泛型、基本类型的自动装箱、改进的循环、枚举类型及可变参数。
2006年11月13日,Java技术的发明者Sun公司宣布,将Java技术作为免费软件对外发布。从2007年3月起,全世界所有的开发人员均可对Java源代码进行修改。
2009年,甲骨文公司宣布收购Sun。
Applet是一种将小程序嵌入到网页中进行执行的技术。
在申请注册商标时,Sun发现Oak已经被人使用了,再想了一系列名字之后,最终,使用了提议者在喝一杯Java咖啡时无意提到的Java词语。
技术架构
JAVASE:全称 Java Platform Standard Edition,Java 2平台的标准版,应用于桌面应用程序;
JAVAEE:Java Platform Enterprise Edition,企业版,应用于WEB开发;
JAVAME:Java Platform Micro Edition,微型版,应用于移动环境和嵌入式设备,例如安卓手机中的应用程序;
跨平台的秘密
java的底层依靠虚拟机,不同的操作系统对应不同的java虚拟机。所以只需要在不同的操作系统中安装对应虚拟机就可以实现不修改java源代码就可以运行。
JRE和JDK
JDK:Java Development Kit,JDK中包含了JRE,JDK是java的开发工具。
JRE:Java Runtime Environment,java程序的运行环境,包含Java运行的所需的类库和JVM。
JVM:Java Virtual Machine,Java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
环境搭建
配置环境变量:就是将在jdkbin目录下指令告知当前系统,在需要使用对应指令的时候由系统根据指定目录寻找指令。
经常被使用的两个指令是javac和java指令,它们分别负责编译和运行java程序。
javac:当执行javac的时候会启动java的编译器对.java文件进行编译,也就是生成.class文件,这是jvm可以识别的字节码文件。
java:会启动jvm,加载运行需要的类库,然后执行.class文件
永久配置方式:
JAVA_HOME=%安装路径%Javajdk
path=%JAVA_HOME%bin
CLASSPATH=;%JAVA_HOME%lib
临时配置方式:
path:C:ProgramJavajdkbin
在定义classpath环境变量时,如果没有定义环境变量classpath,java启动jvm后,会在当前目录下查找要运行的类文件;如果指定了classpath,那么会在指定的目录下查找要运行的类文件;如果classpath值中结尾处有分号那么在指定目录下没有找到类文件的时候,会默认在当前目录下找一次;如果classpath值中结尾处没有分号在指定目录下没有找到类文件的时候会报错。
一般写分号,如果在指定目录下没有找到的话就让它报错,这样方便调试程序。
注释
单行注释(single-line):// 一次只能注释一行,一般是简单注释,用来简短描述某个变量或属性,程序块。
块注释(block):/ 为了进行多行简单注释,一般不使用。/
文档注释:/* 可以使用多行,一般用来对类、接口、成员方法、成员变量、静态字段、静态方法、常量进行说明。Javadoc可以用它来产生代码的文档。为了可读性,可以有缩进和格式控制。 /
语法规则
约定俗成的书写规则
包名:package 的名字应该采用完整的英文描述符,由一个小写单词组成,并且包名的前缀是一个顶级域名,如com、net、org等
类名:class 名应该是个一名词,采用大小写混合的方式,每个单词的首字母大写。一般保证类名简洁而富于描述。
常量:全部采用大写字母,单词之间尽量使用下划线分割。
变量:不可以使用数字和下划线开头;不可以使用关键字。
变量有分成员变量和局部变量。成员变量直接定义在类中,作用于当前类,存在于堆内存中;局部变量可以定义在参数列表和方法内部,作用于当前方法,存在于栈内存中。
所有对象在创建的时候都需要初始化才能使用,做这个工作的是构造函数,其实就是一个与类名称相同的方法,可以重载,不需要返回值。构造函数和一般函数之间的区别除了定义格式上之外还有就是构造函数只被执行一次。
数据类型
基本数据类型:byte、short、int、long、float、double、char、boolean
引用数据类型: 字符串、数组、枚举、接口、对象。
运算符
算术运算符:+、-、*、/、%、+(连接符)、++、--
赋值运算符:=、+=、-=、*=、/=、%=
比较运算符(运算的结果要么是true,要么是false):>、<、==、>=、<=
逻辑运算符(用于连接两个boolean表达式,除!之外):&、|、^、! (二元运算符)、&&(短路与) 、||(短路或)
位运算符(用于操作二进制位的运算符):<<、>>、>>>(无符号右移)
&: 只有两边都为true结果是true。否则就是false。
& 和 &&区别:
& :无论左边结果是什么,右边都参与运算。
&&:短路与,如果左边为false,那么右边不参数与运算。
| : 只要两边都为false的时候结果才是false,否则就是true
| 和|| 区别:
|:两边都参加运算。
||:短路或,如果左边为true,那么右边不参与运算。
流程控制语句
用于决定某个代码块是否可以被执行
if
switch
当判断固定个数的值的时候建议使用switch,效率相对较高。
需要循环执行某个代码块的时候
do while
while
for
foreach
while和for可以相互转换,如果需要定义变量控制循环次数,建议使用for,for循环完毕的时候变量会在内存中释放。
java还提供了两个关键字来帮助细粒化控制流程。
break:作用于switch和循环语句,用于跳出当前循环。
在break关键字下面的代码不会被执行,当有嵌套的时候break只会跳出当前循环,如果需要跳出外部循环,可以给循环打个标记。
continue:作用于循环结构,含义是结束本次循环,开始下次循环。
数组
存储同一类型并且固定长度数据的容器,通过对容器元素编号的方式来访问元素,这样的容器就是数组。
dataType[] arrayRefVar = {value0, value1, ..., valuek};
方法
为了提高代码的复用,可以将一个代码块抽取出一个方法,用于实现某一个或多个功能。
访问修饰符 返回值类型 方法名称(参数类型 形式参数0,参数类型 形式参数1,......){
执行语句;
return 返回值;
}
- return的作用是结束方法。
- 如果方法的返回值是void,系统会自动帮你补上。
- 当方法没有具体的返回值时,返回值类型用void关键字表示。
- 形式参数对应着实际参数,前者的作用是占位,后者是当调用方法的时候传入的参数,这个参数是某个具体的值,因此称为实参。
- 参数的类型用于区分方法重载,方法重载指的是方法名相同参数列表不同,和返回值类型无关。
this
this是java中的关键字,你可以用它来
- 调用本类中的属性,也就是类中的成员变量
- 调用本类中的其他方法
- 调用本类中的其他构造方法
在使用this关键字调用构造方法的时候需要放在构造方法的第一行,否则就会报错,因为构造方法用于初始化,初始化的动作需要一定被执行。
super
super 用于限定本类调用从父类继承得到的实例变量或方法。
- 子类覆盖父类属性的时候可以使用super调用父类属性
- 子类覆盖父类方法的时候可以使用super调用父类方法
- 调用父类的构造方法,必须在首行调用
final
final用于修饰类、方法和变量,被final修饰有如下特点
- 被final修饰的类不可以被继承,其中类中的成员变量都会隐式设置为final,String就是这样一个类。
- 被final修饰的方法不可以被覆盖,被private修饰的方法会隐式地被指定为final方法。
- 被final修饰的变量是一个常量,只能被赋值一次。
- 匿名内部类中使用的外部局部变量只能是final变量。
static
static是一个用于修饰成员变量和方法的修饰符,被static修饰之后有如下特点
- 对象数据共享
- 成员变量可以被类名直接调用
- 静态优先于对象加载
static作用于成员变量时表示只保存一份副本,而final的作用是用来保证变量不可变。
使用static需要注意的地方
- 主函数是被静态修饰
- 静态优先对象加载,所以静态方法只能访问静态成员变量,不能访问非静态成员变量
- this和super关键字也不能在静态中使用,理由同上
- 被静态修饰成员变量和方法会存储到单独的静态区也就是方法区,否则会当作对象的一部分存储在对象区也就是堆区
- 成员变量只能被对象调用而静态变量可以被对象和类名调用
这是面试中常常遇到的问题,如果静态代码块、构造函数、构造代码块同时存在,那么它们先后执行的顺序是:
静态代码块-->构造代码块-->构造函数
abstract
abstract类用于标注一个类是抽象类,目的是不让类实例化,抽象类有如下特点
- 抽象方法只能定义在抽象类中,并且只能修饰方法和类不能修饰变量。
- 抽象方法不负责具体的实现
- 抽象类不可以被实例化
- 当子类通过继承的方式实现了抽象类中的所有抽象方法时,子类才可以实例化,否则该子类也是一个抽象类
- 抽象类有构造方法,是用来给子类对象初始化的
- abstract不可以和final、private和static共存
抽象类的最佳实践是模板设计模式
interface
interface用于修饰一个类为接口,接口用于设计上的好处是
- 功能扩展
- 降低耦合
- 规则约束
- 多继承
接口和抽象的区别
- 抽象类单继承,接口多实现
- 抽象类可以定义非抽象方法,子类继承使用;接口全是抽象方法需要子类实现
- 抽象类可以使用任意修饰符修饰,接口的成员都是public
instanceof
instanceof用于判断一个对象是否是指定的类型
内部类
为了方便访问,直接将B类定义在A类中,那么B类就是A类的内部类。A类可以通过创建B类对象访问B类属性,B类可以直接访问A类属性。如果内部类只需要被使用一次,那么可以定义为匿名类,就是没有命名的内部类,定义匿名内部类的前提是必须继承一个类或者实现一个接口。
异常
java中的异常可以分为运行时异常和编译时异常。在程序运行的时候产生的异常就是运行时异常。
异常被定义在java.lang.Throwable中。处理异常有两种方式,抛出和捕获。
抛出,使用throws关键字抛出异常,子类抛出的异常由父类处理,如果父类无法处理则可以继续往上抛
捕获,当一段代码可能会发生异常的时候或已经发生异常的时候可以使用try/catch处理。
try {
需要被检测的代码;
}
catch(异常类 变量名){
异常处理代码;
}
fianlly{
一定会执行的代码;
}
java提供了很丰富的异常子类,另外开发者还可以自定义异常类丰富异常。
I/O
I/O就是Input/Output,在编程语言中就是输入输出流,编写一个好的输入输出流系统不是一个很好实现的工作。
File
file是java中用于管理文件的类,使用它可以生成文件目录,修改文件名,删除文件,判断文件所在路径等,是I/O非流式的组成部分。
InputStream
inputStream二进制字节输入流,是所有输入流抽象父类。定义输入流所具备的所有特征
OutputStream
outputStream是inputStream的对位抽象类,是所有输出流的父类
Reader
reader是基于字符输入流的抽象类
Writer
writer是基于字符输出流的抽象类
所谓的”流“就是代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象,流的本质是数据传输,设计者将不同的数据类型传输抽象成各种不同的类进行数据操作,因此某某类被定义为流的含义就是为数据之间提供传输通道。
泛型
泛型是JDK1.5引入的新特性,这是java的提供的编译时安全检测机制,本质是参数化类型,将要操作的数据类型被指定为参数,也就是为集合存储的元素指定数据类型,在存储的时候必须存入指定的数据类型的数据。
泛型一般应用于集合,也可以使用在方法和类上,如果你不知道具体的数据类型的话也可以使用通配符"?"来表示未知数据类型。