final关键字
final关键字代表最终、不可改变的。
常见四种用法:
- 可以用来修饰一个类
- 可以用来修饰一个方法
- 可以用来修饰一个局部变量
- 还可以用来修饰一个成员变量
final修饰一个类
格式:
public final class 类名称 {
...
}
含义:当前这个类不能拥有任何的子类
注意:一个类如果是final的,那么其中所有的成员方法都无法被进行覆盖重写。
final修饰一个方法
格式:
修饰符 final 返回值类型 方法名称(参数列表){
//方法体
}
注意事项:对于类来说,abstract和final关键字不能同时使用,因为矛盾。
final修饰局部变量
一旦final来修饰局部变量,那么这个变量就不能进行更改。
一次赋值,终生不变
final int num = 10;
- 对于基本类型来说,不可变说的是变量当中的数据不可改变
- 对于引用类型来说,不可变说的是变量当中的地址值不可改变
final修饰成员变量
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变的。
- 由于成员变量具有默认值,所以用来final之后必须手动赋值,不会再给默认值了
- 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值,二者选其一。
- 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
Java中四种权限修饰符
public > protected > (default) > private
同一个类
同一个包
不同包子类
不同包非子类
注意事项:(default)并不是关键字“default”,而是根本不写。
| public | protected | (default) | private | |
|---|---|---|---|---|
| 同一个类 | YES | YES | YES | YES |
| 同一个包 | YES | YES | YES | NO |
| 不同包子类 | YES | YES | NO | NO |
| 不同包非子类 | YES | NO | NO | NO |
内部类
如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类
- 例如:身体和心脏的关系,汽车和发动机的关系
分类:
- 成员内部类
- 局部内部类(包括匿名内部类)
成员内部类定义格式:
修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
//***
}
//***
}
注意:
- 内部类用外部类,可以随意访问
- 外部类用内部类,要借助内部类对象
成员内部类的使用
- 间接使用:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法
- 直接使用,公式:
类名称 对象名 = new 类名称();
外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称
例子:
package cn.itcast.day4.demo1;
/*如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类
* 例如:身体和心脏的关系,汽车和发动机的关系*/
public class innerClass {
public static void main(String[] args) {
Body body = new Body(); //外部类对象
//通过外部类对象,调用外部类的方法,里面间接在使用内部类,里面间接在使用内部类Heart
body.Bodymethod();
System.out.println("===================");
//按公式写
Body.Heart heart = new Body().new Heart();
heart.beat();
}
}
//外部类
class Body {
public class Heart { //成员内部类
//内部类方法
public void beat(){
System.out.println("心脏跳动!!!");
System.out.println("我叫:" + name);
}
}
//外部类方法
public void Bodymethod(){
System.out.println("外部类方法");
Heart heart = new Heart();
heart.beat();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//外部类的成员变量
private String name;
}
运行结果:
外部类内部类同名变量访问
如果出现了重名现象,格式:外部类名称.this.外部类成员变量名
例子:
public class OutIn {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
inner.methods();
}
}
//如果出现了重名现象,格式:外部类名称.this.外部类成员变量名
class Outer {
int n = 10; //外部类成员变量
public class Inner {
int n = 20; //内部类的成员变量
public void methods(){
int n = 30; //内部类方法的局部变量
System.out.println(n); //局部变量,就近原则
System.out.println(this.n); //内部类的成员变量
System.out.println(Outer.this.n); //外部类的成员变量
}
}
}
运行结果:
局部内部类
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属方法才能使用它,出了这个方法就不能使用了。
定义格式:
修饰符 class 外部类名称 {
修饰符 返回值类型 外部类方法名称(参数列表) {
class 局部内部类名称 {
//。。。
}
}
}
匿名内部类
匿名内部类的定义格式:
接口名称 对象名 = new 接口名称() {
//覆盖重写所有抽象方法
}
如果接口的实现类,或者是父类的子类,只需要使用唯一的一次。
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】
对格式”new 接口名称() {…}“进行解析:
1.new代表创建对象的动作
2.接口名称就是匿名内部类需要实现哪个接口
3.{…} 这才是匿名内部类的内容
注意事项:
- 匿名内部类,在创建对象的使用只能使用唯一一次
- 如果希望多次创建对象,而且类的内容一样的话,就必须使用单独定义的实现类了。
- 匿名对象在调用方法的时候只能调用唯一一次。如果希望同一个对象调用多次,那么必须给这个对象起个名字。
- 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】。
例子:
接口:
public interface MyInterface {
//抽象方法
void method();
}
类:
public class MyInterfaceImpl {
public static void main(String[] args) {
//正常情况
Interfaceimpl impl = new Interfaceimpl();
impl.method();
System.out.println("==============");
//使用匿名内部类,不使用类去implements
MyInterface obj = new MyInterface() {
@Override
public void method() {
System.out.println("匿名内部类实现了方法!!");
}
};
obj.method();
}
}
class Interfaceimpl implements MyInterface {
@Override
public void method() {
System.out.println("实现类覆盖重写了方法!");
}
}
运行结果:
Calendar类
Calendar是日历类
java.util.Calendar类:日历类
- Calendar类是一个抽象类,里面提供了很多操作日历字段的方法(YEAR,MONTH,DAY_F_MONTH)
- Calendar类无法直接创建对象使用,里面有一个静态方法叫getInstance(),该方法返回了Calendar类的子类对象
- static Calendar getInstance 使用默认时区和语言环境获得一个日历
例子:
public class Calendardemo {
public static void main(String[] args) {
Calendar c = Calendar.getInstance(); //多态
System.out.println(c);
}
}
运行结果:
例子:
public class Calendardemo {
public static void main(String[] args) {
demo01();
demo02();
demo03();
}
/*add:根据日历的规则,为指定的日历字段添加或减去指定的时间量
* 参数:
* 1.int field:传递指定的日历字段(YEAR\MONTH)
* 2.int amount:增加/减少指定的值*/
private static void demo03() {
Calendar c = Calendar.getInstance();
//把年增加两年
c.add(Calendar.YEAR,2);
//把月增加3个月
c.add(Calendar.MONTH,3);
//减少一天
c.add(Calendar.DATE,-1);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH); //西方月份0-11
int day = c.get(Calendar.DATE);
System.out.println(year + "年" + (month+1) + "月" + day + "日");
}
/*set:将给定的日历字段设置为给定值
* 参数:1.int field:传递指定的日历字段(YEAR\MONTH)
* 2.int value:给指定字段设置的值*/
private static void demo02() {
Calendar c = Calendar.getInstance();
//设置年
// c.set(Calendar.YEAR,2055);
// //设置月
// c.set(Calendar.MONTH,7);
// //设置日
// c.set(Calendar.DATE,15);
//也可以同时设置年月日
c.set(2099,10,10);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH); //西方月份0-11
int day = c.get(Calendar.DATE);
System.out.println(year + "年" + (month+1) + "月" + day + "日");
}
/* get:返回给定日历字段的值
* 参数:int field:传递指定的日历字段(YEAR\MONTH)
* 返回值:日历字段代表的具体的值 */
private static void demo01() {
//使用getInstance获取日历对象
Calendar c = Calendar.getInstance(); //多态
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH); //西方月份0-11
int day = c.get(Calendar.DATE);
System.out.println(year + "年" + (month+1) + "月" + day + "日");
}
}
运行结果:
System类
java.lang.System类当中提供了大量的静态方法,可以获取与系统相关的信息或系统及操作。
exit终止Java虚拟机
public static void main(String[] args) {
System.out.println("开始");
//exit:终止当前运行的Java虚拟机,非零表示异常终止
System.exit(0);
System.out.println("结束");
}
currentTimeMillis
返回以毫秒为单位的当前时间
例子:
public class SystemDemo {
public static void main(String[] args) {
demo01();
demo02();
}
private static void demo01() {
//程序执行前获取一次毫秒值
long s = System.currentTimeMillis();
//执行for循环
for (int i = 0; i < 9999; i++) {
System.out.println(i);
}
//程序执行后再获取一次毫秒值
long e = System.currentTimeMillis();
System.out.println("程序共耗时:"+(e - s) + "毫秒");
}
}
运行结果:
arraycopy
将数组中指定的数据拷贝到另一个数组当中
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int Length)
参数:
- src - 源数组
- srcPos - 源数组中的起始位置(起始索引)
- dest - 目标数组
- destPos - 目标数据中的起始位置
- Length - 要复制的数组元素的数量
练习
将src数组中前三个元素复制到dest数组的前三个位置上
复制前:src数组元素[1,2,3,4,5] dest数组元素[6,7,8,9,10]
复制后:src数组元素[1,2,3,4,5] dest数组元素[1,2,3,9,10]
public class SystemDemo {
public static void main(String[] args) {
demo02();
}
private static void demo02() {
int[] src = {1,2,3,4,5};
int[] dest = {6,7,8,9,10};
System.out.println("复制前dest数组:" + Arrays.toString(dest));
//使用arraycopy方法
System.arraycopy(src,0,dest,0,3);
System.out.println("复制后dest数组:" + Arrays.toString(dest));
}
}
运行结果:
Debug
Debug概述
Debug:是供程序员使用的程序调试工具,可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序
Debug操作流程
debug调试,又被称为断点调试,断点其实是一个标记,告诉我从哪里开始查看
- 如何加断点:选择要设置断点的代码行,在行号区域后面单击鼠标左键即可。
- 如何运行加了断点的程序:在代码区域右键debug执行
- 看哪里:看debug窗口
看console窗口中的结果展示
- 点哪里
点step into(F7)箭头,就可以继续向下执行
- 如何删除断点
选择要删除的断点,单击鼠标左键即可
一次性删除断点
一起学习,一起进步 -.- ,如有错误,可以发评论