文章目录
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
$ javac HelloWorld.java
$ java HelloWorld
Hello World
Java概述
JDK: Java Development Kit,是提供给 Java 程序员的开发工具包,换句话说,没有 JDK,Java 程序员就无法使用 Java 语言编写 Java 程序。也就是说,JDK 是用于开发 Java 程序的最小环境。
JRE: Java Runtime Environment,提供给 Java 程序运行的最小环境,换句话说,没有 JRE,Java 程序就无法运行。
Java基础语法
标识符
关键字
用户自定义标识符
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
所有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始
首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合
关键字不能用作标识符
标识符是大小写敏感的
合法标识符举例:age、$salary、_value、__1_value
非法标识符举例:123abc、-salary
修饰符
- 访问修饰符
default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
public : 对所有类可见。使用对象:类、接口、变量、方法
protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
- 非访问修饰符
static 修饰符,用来修饰类方法和类变量。
final 修饰符,用来修饰类、方法和变量,
final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
运算符
-
算术运算符
-
关系运算符
-
位运算符
-
逻辑运算符
-
赋值运算符
-
其他运算符
variable x = (expression) ? value if true : value if false
( Object reference variable ) instanceof (class/interface type)
String name = "James";
boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
数据类型
- 基本数据类型
byte
short
int
long
float
double
char
boolean
- 引用数据类型
在Java中,引用类型的变量非常类似于C/C++的指针。
引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
对象、数组都是引用数据类型。
所有引用类型的默认值都是null。
一个引用变量可以用来引用任何与之兼容的类型。
Site site = new Site("Runoob"); //site就是类引用
常量
常量值
定义常量
常量在程序运行时是不能被修改的。
final double PI = 3.1415927;
变量
DataType identifier;
DataType identifier=value;
DataType:变量类型,如 int、string、 char 和 double 等。
identifier:标识符,也叫变量名称。
value:声明变量时的值。
- 类变量(静态变量):独立于方法之外的变量,用 static 修饰。
- 实例变量(成员变量):独立于方法之外的变量,不过没有 static 修饰。
- 局部变量:类的方法中的变量。
public class Variable{
static int allClicks=0; // 类变量
String str="hello world"; // 实例变量
public void method(){
int i =0; // 局部变量
}
}
控制流程
- 顺序结构
- 循环结构
while
循环do…while
循环for
循环break
和continue
- 条件结构
if...else
语句switch case
语句
- Java 增强 for 循环
for(声明语句 : 表达式)
{
//代码句子
}
声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
String类
字符串广泛应用在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
length()
方法,它返回字符串对象包含的字符数。concat()
方法,连接两个字符串。
string1.concat(string2);
- 输出格式化字符串
System.out.printf("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
"is %s", floatVar, intVar, stringVar);
String fs;
fs = String.format("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);
String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了
给一个已有字符串"abcd"第二次赋值成"abcedl",不是在原内存地址上修改数据,而是重新指向一个新对象,新地址。
StringBuffer和StringBuilder类
和 String 类是不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,
所以如果需要对字符串进行修改推荐使用 StringBuffer。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
数组
dataType[] arrayRefVar; // 首选的方法
或
dataType arrayRefVar[]; // 效果相同,但不是首选方法
建议使用
dataType[] arrayRefVar
的声明风格声明数组变量。
dataType arrayRefVar[]
风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员能够快速理解java语言。
包
Java 引入了包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突、类文件管理等问题。
面向对象
对象和类
方法(method)
类似C语言中的函数
public class Dog {
String breed;
int size;
String colour;
int age;
//方法
void eat() {
}
void run() {
}
void sleep(){
}
void name(){
}
}
方法重写(Override)与重载(Overload)
面试爱考
- 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
- 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
方法的重写和重载是Java多态性的不同表现。
构造方法(构造器)
每个类都有构造方法。如果没有显式地为类定义构造方法,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 myPuppy = new Puppy( "tommy" );
}
}
访问实例变量和方法
/* 实例化对象 */
Object referenceVariable = new Constructor();
/* 访问类中的变量 */
referenceVariable.variableName;
/* 访问类中的方法 */
referenceVariable.methodName();
源文件声明规则
当在一个源文件中定义多个类,并且还有import
语句和package
语句时,要特别注意这些规则。
- 一个源文件中只能有一个
public
类 - 一个源文件可以有多个非
public
类 - 源文件的名称应该和
public
类的类名保持一致。例如:源文件中public
类的类名是Employee
,那么源文件应该命名为Employee.java
。 - 如果一个类定义在某个包中,那么
package
语句应该在源文件的首行。 - 如果源文件包含
import
语句,那么应该放在package
语句和类定义之间。如果没有package
语句,那么import
语句应该在源文件中最前面。 import
语句和package
语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。
继承
class 父类 {
}
class 子类 extends 父类 {
}
extends
关键字implements
关键字super
与this
关键字
tips:
子类是不继承父类的构造器(构造方法或者构造函数),它只是调用(隐式或显式)。
如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则子类的构造器不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
多态的实现方式
- 方式一:重写
- 方式二:接口
- 方式三:抽象类和抽象方法
接口
实际开发时,继承顶多一层,项目代码主要在实现接口这一块。
//定义
[访问权限] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
//实现
...implements 接口名称[, 其他接口名称, 其他接口名称..., ...] ...
为什么有了抽象类,设计人员还要不予余力的引入接口概念呢?
- 首先考虑的是抽象类的局限性。子类只能继承与一个父类,而实现类可以引入多个接口,在实际项目中当要改动一些方法的具体代码,无需删除本来的代码,从新写一个实现类,更换接口引用的对象即可。
- 其次是接口的松耦合是我们可以编写可复性高的代码。比如Server层本来引用使用Dao层mysql数据库的实现类,现在遇到mysql解决不了的业务,需要orcale实现,难道你要为了这一个或几个的功能,把所有的引用mysql的全删掉重写?只要再写一个dao层的实现类去引用这个接口,遇到需要orcale方法使用哪个接口变量就好了,别人写的代码也无需去删改。抽象类可以再写一个子类,但子类却不受父类过多约束,随意添加方法,对于项目的协同工作不利。
抽象类做不到对修改封闭,对扩展开放的原则。- 再者接口更加安全,严密,接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些。对于开发,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。
接口回调
抽象类和抽象方法
和接口类似
abstract class //抽象类
abstract method //抽象方法
- 抽象类
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。 - 抽象方法
如果一个类包含抽象方法,那么该类必须是抽象类。
继承抽象方法的子类必须重写该方法,否则该子类也必须声明为抽象类。
必须要有子类实现该抽象方法,否则,从最初的父类到最终的子类都不能用来实例化对象。
匿名类
集合框架
-
集合(Collection)
-
图(Map)
-
Iterator(迭代器)
类似一个智能指针,没有C语言指针的缺点。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
Iterator 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.Iterator; // 引入 Iterator 类
ArrayList
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化
E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
objectName: 对象名
LinkedList
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
LinkedList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
// 引入 LinkedList 类
import java.util.LinkedList;
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
HashSet
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合
HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.HashSet; // 引入 HashSet 类
HashSet<String> sites = new HashSet<String>();
HashMap
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
HashMap 类位于 java.util 包中,使用前需要引入它,语法格式如下:
import java.util.HashMap; // 引入 HashMap 类
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
IO
- 按照传输方式分类
- 按操作对象
异常处理
- 捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//Catch 块
}