目录
4、使用Date和SimpleDateFormat类表示时间
慕课网java工程师学习规划:http://www.imooc.com/course/programdetail/pid/31
一、Java初体验
1、Java简介
JDK:Java Development Kit(Java开发工具包)
JRE:Java Runtime Environment(Java运行环境)
2、Java开发环境搭建
JAVA_HOME:配置JDK安装路径
PATH:配置JDK命令文件的位置(jdk下的bin目录)
CLASSPATH:配置类库文件的位置(jdk下的lib目录)
3、使用记事本编写Java程序
1)源文件:记事本编写HelloWorld.java
public class HelloWorld{//与文件名相同
public static void main(String[] args){
System.out.println("Welcome!");
}
}
HelloWorld.java文件存放在d盘根目录下。
2)编译:cmd命令行进入d盘,输入javac HelloWorld.java
3)字节码文件:d盘多出一个HelloWorld.class文件
4)解释器执行:cmd命令行输入java HelloWorld(注意:不是java HelloWorld.java
5)输出结果
4、使用Eclipse开发Java程序
IDE(集成开发环境):一类软件将程序开发环境和程序调试环境集合在一起,提高开发效率。例如:MyEclipse、NetBeans
IntelliJ IDEA
5、MyEclipse的使用简介
MyEclipse是对Eclipse的扩展
6、程序的移植
导出:项目右键属性,找到项目的位置,复制。
导入:在空白处右键导入
二、变量和常量
1、Java中的关键字
2、Java标识符
1. 标识符可以由字母、数字、下划线(_)、美元符($)组成,但不能包含 @、%、空格等其它特殊字符,不能以数字开头。譬如:123name 就是不合法滴
2. 标识符不能是 Java 关键字和保留字( Java 预留的关键字,以后的升级版本中有可能作为关键字),但可以包含关键字和保留字。如:不可以使用 void 作为标识符,但是 Myvoid 可以
3. 标识符是严格区分大小写的。 所以涅,一定要分清楚 imooc 和 IMooc 是两个不同的标识符哦!
4. 标识符的命名最好能反映出其作用,做到见名知意。
3、变量
变量类型、变量名和变量值
4、Java中的数据类型
Java语言是一种强类型语言。即在Java中存储的数据都是有类型的,而且必须在编译时就确定其类型。
Java中有两类数据类型:基本数据类型和引用数据类型。
基本数据类型变量存放的是数据本身,引用数据类型变量存放的是保存数据的空间地址。(基本数据类型存放的是直接放在抽屉里的东西,引用数据类型存放的是这个抽屉的钥匙)
String是常见的引用数据类型,用来表示字符串。
5、变量的使用规则
1)Java中的变量需要先声明后使用
2)可以声明的同时进行初始化,也可以先声明后赋值。
3)变量每次只能赋一个值,但可以修改多次。
4)main方法中定义的变量必须先赋值,然后才能输出。
5)变量名不建议使用中文(语法没有提示错误),容易产生安全隐患,譬如后期跨平台操作时出现乱码等。
6、Java中的类型转换
1)自动类型转换:
自动类型转换是需要满足特定的条件的:1)目标类型能与源类型兼容,如double型兼容int型,但char型不能兼容int型;2)目标类型大于源类型,如double类型长度为8字节,int类型为4字节,因此double类型的变量里直接可以存放int类型的数据,但反过来就不可以了。
2)强制类型转换:
语法:(数据类型)数值
7、Java常量的应用
语法:final 常量类型 常量名=值;
常量名一般使用大写字母
8、Java中的注释
Java中注释有三种类型:单行注释、多行注释、文档注释。
文档注释以/**开头,*/结尾,多行注释以/*开头,*/结尾,单行注释以//开头,行末结尾。
使用文档注释时还可以使用javadoc标记,生成更详细的文档信息:
@author 标明开发该类模块的作者
@version 标明该类模块的版本
@see 参考转向,也就是相关的主题
@param 对方法中某参数的说明
@return 对方法返回值的说明
@exception 对方法可能抛出的异常进行说明
三、常见的运算符
1、算数运算符
+、-、*、/、%、++、--
++、--出现在操作数的左边和右边结果不同。
例如:
1)int a=5;
int b=++a;//a先自增,然后将值赋给变量b
a:6,b:6
2)int a=5;
int b=a++;//先将a的值赋给变量b,然后再自增
a:6,b=5
自增和自减运算符只能用于操作变量,不能直接用于操作数值或常量。
2、赋值运算符
=、+=、-=、*=、/=、%=
3、比较运算符
>、<、>=、<=、==、!=
>、<、>=、<=只支持左右两边操作数是数值类型,==、!=两边的操作数既可以是数值类型,也可以是引用类型。
==与equals的区别:
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址。
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;对equals方法进行了重写的话,比较的是所指向的对象的内容,如String。
4、逻辑运算符
&&、||、!、^
5、条件运算符
? :
6、运算符的优先级
四、流程控制语句
1、条件语句
if、if…else…、多重if、嵌套if、switch
1)switch中的case匹配后,执行匹配块里的程序代码,如果没有遇见break会继续执行下一个case块的内容,直到遇到break语句或者switch语句块结束。
2)可以把功能相同的case语句合并起来。例如:
case 1:
case 2:
System.out.println(“XXX”);
3)default块可以出现在任意位置,也可以省略。
2、循环语句
while、do…while、for
3、循环跳转语句
break、continue
4、多重循环
使用Scanner工具类来获取用户输入:
Scanner类位于java.util包中,使用时需要导入此包。
步骤:
- 导入java.util.Scanner
- 创建Scanner对象
- 接收并保存用户输入的值
import java.util.Scanner;
Scanner input=new Scanner(System.in);
input.next();
input.nextLine(); (input.nexInt();input.nextDouble();在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取)
断点调试:
在左端双击,设置断点;点击工具栏debug按钮(类似甲壳虫),打开调试视图,程序执行到设置断点的地方不在继续执行;点击工具栏step over按钮(F6快捷键),一步一步向下执行。
五、数组
1、数组的定义
数组可以按照顺序存放多个类型相同的数据。
2、数组的使用
1)声明数组
数据类型[] 数组名;
或数据类型 数组名[];
2)分配空间
数组名=new 数据类型[数组长度];
可以将上面两步合并,在声明数组的同时为它分配空间。
例如:int[] scores=new int[5];
Java还提供了另外一种直接创建数组的方式,它将声明数组、分配空间和赋值合并完成。
例如:int[] scores={78,91,84,68};
等价于int[] scores=new int[]{78,91,84,68};(中括号里必须空格,不能指定长度)
3、使用Arrays类操作Java中的数组
Arrays类是Java中提供的一个工具类,该类中包含了一些方法用来直接操作数组。
import java.util.Arrays;//导入包
1)排序
Arrays.sort(数组名);
2)将数组转换为字符串
Arrays.toString(数组名);
3)将数组转化为list
Arrays.asList(数组名)
4、使用foreach操作数组
for(类型 元素变量:遍历对象){
执行的代码
}
例如:String[] hobbys={“c”,“java”,“python”};
for(String hobby : hobbys){
System.out.println(hobby);
}
5、二维数组
1)声明数组并分配空间:
数据类型[][] 数组名=new 数据类型[行的个数][列的个数];
或者
数据类型[][] 数组名; 数组名=new 数据类型[行的个数][列的个数];
2)赋值
可以通过下标来逐个赋值,也可以在声明数组的同时为其赋值
数据类型[][] 数组名={{值1,值2…},{值1,值2}…};
3)处理数组
使用二重循环来输出二维数组中的每一个元素:
注:定义二维数组时可以只指定行的个数,然后再为每一行分别指定列的个数。如果每行列数不同,则创建的是不规则的二维数组。
六、方法
1、方法的定义
访问修饰符:可以是public、protected、private甚至可以省略。
返回值类型:如果方法不返回任何值,则返回值类型指定为void;如果方法具有返回值,则需要指定返回值的类型,并且在方法体中使用return语句返回值。
2、方法重载
同一个类中包含了两个或两个以上方法名相同、方法参数的个数、顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了。
方法重载必须是在同一个类中,方法名相同,方法参数的个数、顺序或类型不同,与方法的修饰符或返回值没有关系。
Math类是用于进行算数操作的类
Java中存在着两种Random函数:
1)java.lang.Math.random
Math.random()生成0-1的浮点数,通过(int)(Math.random()*100)生成100以内的随机数。
2)java.util.Random
Random r=new Random();//默认当前系统时间的毫秒数作为种子数
或Random r1=new Random(25);//构造Random对象的时候指定种子
r.nextInt(100);//产生随机数为0-100的整数,不包括100
七、类和对象
1、什么是类和对象
类是具有相同属性和方法的一组对象的集合。
类是抽象的概念。对象是看得到、摸得着的具体实体,是客观存在的。
2、类
定义类的步骤:
1)定义类名
2)定义属性(0、1或多个属性)
成员变量就是类里面的变量,不区分static;没有static的成员变量叫实例变量,加了static的成员变量叫类变量(静态变量)
3)定义方法(0、1或多个方法)
3、对象
1)创建对象
类名 对象名=new类名();
new类名():实例化
对象和对象的引用
2)使用对象
对象名.属性
对象名.方法
4、成员变量和局部变量
1)成员变量
在类中定义,用来描述对象将要有什么;可以被本类方法和其他类的方法使用
2)局部变量
在类的方法中定义,在方法中临时保存数据;只能在当前方法中使用;Java不给局部变量初始值。
两类变量同名时,局部变量具有更高的优先级。(就近原则)
5、构造方法
1)使用new+构造方法创建一个新的对象
2)构造方法是定义在Java类中的一个用来初始化对象的方法,与类名相同,没有返回类型,可以指定参数(无参构造方法和有参构造方法)
6、静态变量
Java中被static修饰的成员称为静态成员或类成员。静态成员可以使用类名直接访问,也可以使用对象名进行访问。
static可以修饰变量、方法和代码块。
7、静态方法
使用static修饰方法,称为静态方法或类方法。main方法就是静态方法。
在普通成员方法中,可以直接访问同类的非静态变量和静态变量;静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。
8、静态初始化块
Java中可以通过初始化块进行数据赋值。
静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。(main方法是在类运行时执行,先执行static再执行main方法)
八、封装
1、什么是封装
将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
封装的实现步骤:
1)修改属性的可见性:设为private
2)创建getter/setter方法:属性的读写
3)在getter/setter方法中加入属性控制语句
2、Java中的包
系统中的包:
java.lang.(类) 包含java语言基础的类
java.util.(类) 包含java语言中各种工具类
java.io.(类) 包含输入、输出相关功能的类
使用import关键字,包的命名规范全是小写字母拼写。
3、访问修饰符
4、this关键字
this关键字代表当前对象
this.属性 操作当前对象的属性;this.方法 调用当前对象的方法。
5、内部类
内部类是定义在另外一个类里面的类。与之对应,包含内部类的类称为外部类。
内部类的作用:
- 提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其它类访问该类。
- 内部类的方法可以直接访问外部类的所有数据,包括私有的数据。
- 内部类所实现的功能使用外部类同样可以实现,只是有时候使用内部类更方便。
内部类分以下几种:
成员内部类
静态内部类
方法内部类
匿名内部类
6、成员内部类
定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去new一个内部类对象,即:内部类 对象名=外部类对象.new 内部类();
编译程序后,会产生两个.class文件,外部类$内部类.class、外部类.class
如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用this关键字。如:
7、静态内部类
1)静态内部类不能直接访问外部类的非静态成员,但可以通过new 外部类().成员的方式访问。
2)如果外部类的静态成员与内部类的成员名称相同,可通过”类名.静态成员”访问外部类的静态成员;如果不相同,可通过“成员名”直接调用外部类的静态成员。
3)创建静态内部类的对象时,不需要外部类的对象,可以直接创建:内部类 对象名=new 内部类()。
8、方法内部类
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和static修饰符。
9、匿名内部类
通常在接口部分使用
IPlayGame.java:
public interface IPlayGame {
public void playGame();
}
测试类的main方法中:
IPlayGame ip3=new IPlayGame(){
@Override
public void playGame() {
System.out.println("使用匿名内部类 的方式实现接口");
}
};
ip3.playGame();
或者
new IPlayGame(){
@Override
public void playGame() {
System.out.println("使用匿名内部类 的方式实现接口1");
}
}.playGame();
九、继承
1、Java中的继承
继承是类与类的一种关系,是”is a”的关系。
子类、派生类 父类、基类
Java中的继承是单继承,一个类只有一个父类。
2、方法的重写
子类对继承父类的方法不满意,可以重写父类继承的方法,当调用方法时会优先调用子类的方法。
返回值类型、方法名、参数类型及个数都要与父类继承的方法相同,才叫方法的重写。
3、Java中继承初始化的顺序
先父类对象属性初始化,执行构造方法;再子类对象属性初始化,执行构造方法。
4、final
final关键字可以修饰类、方法、属性和变量
final修饰类,则该类不允许被继承
final修饰方法,则该方法不允许被覆盖(重写)
final修饰属性,则该类的初始化属性必须有值,或在构造方法中赋值。
final修饰变量,则该变量的值只能赋一次值,即为常量。
5、super
在对象的内部使用,可以代表父类对象。
访问父类的属性:super.属性
访问父类的方法:super.方法()
如果子类的构造方法中没有显示调用父类的构造方法,则系统默认调用父类无参的构造方法。如果显示的调用构造方法,必须在子类构造方法的第一行。
6、Java中的Object类
Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。java.lang.object
toString()方法:
在main方法中直接输出某个对象的值,输出的是在内存中的地址(哈希码),前面加上类的包名。
通过重写toString()方法输出对象的属性。
equals()方法:
比较对象的引用是否指向同一块内存地址。
obj.getClass():类的对象,描述类的代码信息,类有哪些属性、什么类型、变量名是什么,有哪些方法、方法名是什么,方法里的代码是什么。
obj:类对象,对象的属性值的信息(数据信息),例如对象有 age属性,是18还是20。
十、多态
1、Java中的多态
对象的多种形态
继承是实现多态的基础。
1)引用多态:父类的引用可以指向本类的对象,父类的引用可以指向子类的对象
2)方法多态:
创建本类对象时,调用的方法为本类方法。
创建子类对象时,调用的方法为子类重写的方法或者或者继承的方法。
2、引用类型转换
1)向上类型转换(隐式/自动类型转换),是小类型到大类型的转换。无风险
2)向下类型转换(强制类型转换),是大类型到小类型。有风险
instanceof运算符,来解决引用对象的类型,避免类型转换的安全性问题。
用法:object instanceof class ,返回一个布尔类型。
Dog dog=new Dog();
Animal animal=dog;
if(animal instanceof Dog){
Dog dog1=(Dog)animal;
}else{
System.out.println("无法进行类型转换为Dog类型");
}
if(animal instanceof Cat){
Cat cat=(Cat)animal;
}else{
System.out.println("无法进行类型转换为Cat类型");
}
运行结果:无法进行类型转换为Cat类型。
3、抽象类
1)在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
2)从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。
不关注子类的实践
使用规则:
- abstract定义抽象类
- abstract定义抽象方法,只声明,不需要实现
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。(抽象类可以包含普通的方法,需要实现)
- 抽象类不能直接创建,可以定义引用变量指向子类对象
例如:
Shape类:
public abstract class Shape {
public abstract void area();
public abstract void perimeter();
}
Circle类:
public class Circle extends Shape {
private int r;
final double PI=3.14;
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
@Override
public void area() {
System.out.println("面积为:"+PI*r*r);
}
@Override
public void perimeter() {
System.out.println("周长为:"+2*PI*r);
}
}
Rectangle类:
public class Rectangle extends Shape {
private int longth;
private int width;
public int getLongth() {
return longth;
}
public void setLongth(int longth) {
this.longth = longth;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
@Override
public void area() {
System.out.println("长方形面积为:"+longth*width);
}
@Override
public void perimeter() {
System.out.println("长方形周长为:"+2*(longth+width));
}
}
测试类:
public class ShapeTest {
public static void main(String[] args) {
Circle circle=new Circle();
Rectangle rect=new Rectangle();
circle.setR(2);
rect.setLongth(5);
rect.setWidth(4);
circle.area();
circle.perimeter();
rect.area();
rect.perimeter();
}
}
4、接口
[修饰符] (abstract) interface 接口名 [extends 父接口1,父接口2…]{
零个到多个常量定义…
零个到多个抽象方法定义…
}
接口就是用来被继承、被实现的,修饰符一般建议使用public,不能使用private和protected修饰接口。
常量:public static final修饰符(不建议使用)
方法:public abstract修饰符
一个类可以实现一个或多个接口,实现接口使用implements关键字。
如果继承父类,继承父类必须在实现接口之前。
5、UML简介
用例图
序列图
类图
十一、异常
1、异常简介
Java中所有不正常的类都继承至Throwable类(万恶之源)
Throwable类有两个子类:Error和Exception
Error指系统错误比如内存溢出,虚拟机异常等。
Exception(异常)编码、环境、用户操作出现问题。
Exception的子类:
1)(Unchecked exception)非检查异常:RuntimeException运行时异常
空指针异常(NullPointerException)、数组下标越界异常(ArrayIndexOutOfBoundsException)、类型转换异常(ClassCastException)、算数异常(ArithmeticException)
运行时异常会由Java虚拟机自动抛出自动捕获,代码本身有问题,从逻辑上改进代码
2)(Checked exception)检查异常:
文件异常(IOException文件不存在)、SQL异常(SQLException连接错误)
手动添加捕获及处理
2、处理异常
try-catch以及try-catch-finally
编写多重catch语句块,按照先小后大,先子类后父类的方式。
finally释放占用的资源,如关闭连接等
3、Java中的异常抛出以及自定义异常
throw:将产生的异常抛出
throws:声明要抛出何种类型的异常
public void 方法名(参数列表) throws 异常列表{
throw new Exception();
}
自定义异常:
public class DrinkException extends Exception{
public DrinkException(){
}
public DrinkException(String message){
super(message);
}
}
继承相近的异常或所有异常的父类。
4、异常链
public class ChainException {
//test1():抛出喝大了异常
//test2():调用test1(),捕获喝大了异常,并且包装成运行时异常,继续抛出
//main方法中,调用test2(),尝试捕获test2()方法抛出的异常
public static void main(String[] args) {
ChainException ce=new ChainException();
try{
ce.test2();
}catch(Exception e){
e.printStackTrace();
}
}
public void test1() throws DrinkException{
throw new DrinkException("喝酒别开车啊喂~");
}
public void test2(){
try {
test1();
} catch (DrinkException e) {
// TODO Auto-generated catch block
RuntimeException rte=new RuntimeException("司机一滴酒,亲人两行泪 ");
rte.initCause(e);//调用initCause方法,把捕获的DrinkException传递进去
throw rte;//抛出新异常
}
}
}
十一、字符串
1、字符串定义
public class HelloWorld {
public static void main(String[] args) {
String s1 = "imooc";
String s2 = "imooc";
String s3="I love "+s1;
String s4 = "I love "+s1;
// 比较字符串s1和s2
// imooc为常量字符串,多次出现时会被编译器优化,只创建一个对象
System.out.println("s1和s2内存地址相同吗?" + (s1 == s2));
//比较字符串s1和s3
System.out.println("s1和s3内存地址相同吗?" + (s1==s3));
//比较字符串s4和s3
// s1是变量,s4在运行时才知道具体值,所以s3和s4是不同的对象
System.out.println("s3和s4内存地址相同吗?" + (s4 == s3));
}
}
2、String类的常用方法
3、StringBuilder类
String类具有不可变性。
例:
输出结果:
hellowoeld
hello(str仍然为hello)
程序运行时会额外创建一个对象,保存”helloworld”,当频繁操作字符串时,就会额外产生很多临时变量。使用StringBuilder和StringBuffer可以避免这个问题。
StringBuilder和StringBuffer基本相似,不同是StringBuffer是线程安全的,StringBuilder则没有线程安全功能,所以性能略高。因此一般情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用StringBuilder类。
(String类具有不可变性,其字符串发生改变后会创建新的位置来存储;而StringBuilder和StringBuffer是在原有对象上进行修改,其位置不变。 )
StringBuilder类的方法:
十二、Java中必须了解的常用类
1、Java中的包装类
为了让基本数据类型也具备对象的特征,Java为每个基本数据类型都提供了一个包装类。
包装类主要提供了两大类方法:
- 将本类型和其他基本类型进行转换的方法
- 将字符串和本类型及包装类相互转换的方法。
例如:Integer包装类的常用方法
2、基本类型和包装类之间的转换
JDK1.5引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更加轻松便利了。
装箱:把基本类型转换成包装类,使其具有对象的性质,可分为手动装箱和自动装箱。
拆箱:和装箱相反,把包装类转换成基本类型的值,可分为手动拆箱和自动拆箱。
3、Java中基本类型和字符串之间的转换
基本类型转换为字符串有三种方法:
- 使用包装类的toString()方法
- 使用String类的valueOf()方法
- 用一个空字符串加上基本类型,得到的就是基本数据对应的字符串。
将字符串转换成基本类型有两种方法:
- 调用包装类的parseXXX静态方法
- 调用包装类的valueOf()方法转换为基本类型的包装类,会自动拆箱。
4、使用Date和SimpleDateFormat类表示时间
Date类在java.util包中,主要作用就是获取当前时间。
使用Date类的默认无参构造方法创建出的对象就代表当前时间。
输出结果:
Date date= new Date(long date)//分配
,从1970 年 1 月 1 日00:00:00以来的毫秒数Date
对象并初始化此对象
默认的时间格式不是很友好,可以使用java.text包中的SimpleDateFormat类来对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期。
1)使用format()方法将日期转换为指定格式的文本
运行结果:
2014-06-11 09:55:48
2)使用parse()方法将文本转换为日期
运行结果:
注:使用SimpleDateFormat对象的parse()方法时可能会出现转换异常,即ParseException,因此需要进行异常处理。
5、calendar类的应用
java.util.Calendar类是一个抽象类,可以通过调用getInstance()静态方法获取一个 Calendar对象,此对象已由当前日期时间初始化,即默认当前时间。
运行结果:
Calendar类提供了getTime()方法,用来获取Date对象,完成Calendar和Date的转换,还可以通过getTimeInMillis()方法,获取此Calendar的时间值,以毫秒为单位。
运行结果:
6、使用Math类操作数据
Math类位于java.lang包中,包含用于执行基本数学运算的方法,Math类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名。