代码规范!
使用GBK是因为老师要授课,要在DOS系统中显示中文,所以用GBK。一般编码都是用UTF-8
…\ 是从当前目录返回到上一级目录
cd /D c: 中,/D 可切换根目录。
JRE JVM JDK 的关系
JDK = JRE + Java开发工具
JRE = JVM + 核心类库
环境变量path配置及其作用
Java中判断字符串相等,不能用==,假设String a = “12454”;
判断a是否和字符串12454相等的方法:
a.euqals("12454")
使用Java从键盘输入数据
import java.util.Scanner;
public class Input {
public static void main(String[] args){
/*
* 1. Scanner类表示简单文本扫描器,在java.util包
* 2. 导入Scanner类所在的包
* 3. 创建Scanner对象,new一个,
*/
Scanner scanner = new Scanner(System.in);
String name = scanner.next(); //接收用户的string
int age = scanner.nextInt(); //接受用户的年龄 int
double salary = scanner.nextDouble(); //接受用户的薪水 salary
System.out.println("name="+ name +" age=" + age + " salary=" + salary);
scanner.close();
}
}
使用Acwing编写java
import java.util.Scanner;
public class Main{
public static void main(String[] args){
int a,b;
Scanner scanner = new Scanner(System.in);
a = scanner.nextInt();
b = scanner.nextInt();
System.out.println(a+b);
}
}
使用java随机数
import java.util.Random;
public class RANDOM{
public static void main(String[] args){
int[] a = new int[10];
Random random = new Random();
for(int i=0;i<a.length;i++)
a[i] = random.nextInt(100);
for(int i=0;i<a.length;i++)
System.out.print(a[i] + " ");
}
}
使用java实现冒泡排序
import java.util.Random;
public class BubbleSort {
public static void main(String[] args){
int[] a = new int[10];
Random random = new Random();
for(int i=0;i<a.length;i++)
a[i] = random.nextInt(100);
for(int i=0;i<a.length;i++)
System.out.print(a[i] + " ");
int n = a.length;
for(int i=1;i<n;i++)
for(int j=0;j<n-i;j++)
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
System.out.println();
for(int i=0;i<a.length;i++)
System.out.print(a[i] + " ");
}
}
int... nums
表示接受任意多个int。可以理解为nums是个数组目标:匹配所有四个数字
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReGTheory {
public static void main(String[] args){
String content = "Java 的历史要追溯到 1991 年,由 Sun公1998司带领的开2456发小组,"+
"想设计一种小型的计算机语言,主要用于有线电视转换盒这类的消费设备。"+
"由于这类设备的处理能力和内存都非常有限,所以语言就必须设计的非常小且能够生成紧凑的代码。"+
"另外,由于不同的厂商会选择不同的 CPU, 因此很重要的一点就是这种语言不应该与任何特定的体系结构绑定。这个项目被命名为 “Green”。1996 年"+
", Sun 发布了第一个 Java 1.0 版本。 ";
//1.生成正则表达式
String regStr = "(\\d\\d)(\\d\\d)";
//2.创建模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
//3.创建匹配器
//说明:创建匹配器matcher,按照正则表达式pattern的规则去匹配content字符串
Matcher matcher = pattern.matcher(content);
//4.开始匹配
while(matcher.find()){
System.out.println("找到"+matcher.group(0));
}
}
}
matcher.find()完成的任务
matcher.group(0)分析
源码:
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
根据groups[0]=13 和groups[1]= 17的记录的位置,从content开始截取子字符串(从groups[0]~groups[1])返回。
如果再次使用find方法,仍然按照上面分析来执行。后面再用时,groups[0]和groups[1]的值就变成下一个匹配的子字符串的位置。
分组为什么是group(0),有什么含义?
groups[0] groups[1]分别表示整个匹配到的子字符串的起止位置。
groups[2]和groups[3]分别表示第一个分组的起止位置,第1组即group(1)
groups[4]和groups[5]分别表示第二个分组的起止位置,第2组即group(2)
groups[6]和groups[7]分别表示第三个分组的起止位置,第3组即group(3)
所以上面为什么是get-Sequence(groups[group * 2], groups[group * 2 + 1])呢
整个是0*2=0,0*2+1=1,所以groups[0] groups[1]表示整个的子字符串
第一组group(1):1*2=2,1*2+1=3
第二组group(2): 2*2=4, 2*2+1=5
第三组group(3):3*2=6,3*2+1=7.
小结:
如果正则表达式有() 即分组:
取出匹配的字符串规则如下:
group(0)表示匹配到的整个子字符串
group(1)表示匹配到的子字符串的第1组字符串
group(2)表示匹配到的子字符串的第2组字符串
group(3)表示匹配到的子字符串的第3组字符串
下标注意不能越界。分组数不能越界。
正则转义符中,Java中两个反斜杠才代表一个反斜杠。\( 才能匹配到(。
(?i)abc 表示不区分大小写abc。
在编译正则表达式时,直接就选择忽略大小写:
Pattern pattern = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
System.out.println("匹配成功");
}
else System.out.println("匹配失败");
//验证url
String content = "https://www.bilibili.com/video/BV1Eq4y1E79W/?p=17&spm_id_from=pageDriver&vd_source=4283306641c7c0c69e8d362d4f1b4e97";
String regStr = "^((http|https)://)([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&#/%.]*)?$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if(matcher.find()){
System.out.println("匹配成功");
}
else System.out.println("匹配失败");
Pattern类的matches方法
不使用先定义pattern,再使用matcher,直接使用matches
这里如果是判断一个字符串是否可以和一个正则表达式整体匹配,。只能判断整体 全部匹配
上面的只是找到了就可以。matcher.find()
Pattern.matches(regStr, content); //先写正则表达式串,再写字符串内容
使用pattern将字符串替换为别的字符串
// 使用patcher实现正则表达式的替换。此替换是返回新的字符串,原内容不变。
String regStr = "lgq";
String content = "agfkjisagjwlgqfggwseafgserffjiqaflgqglgqdajoifglgq";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
String newContent = matcher.replaceAll("刘广琦"); //replaceAll中参数为替换后的字符串
System.out.println("替换后的新字符串为" + newContent);
**反向引用 **
反向引用:
内部反向引用用 \\分组号
,外部反向引用用$分组号
String content = "(\\d)(\\d)\\2{2}\\1{1}" //匹配类似122211 155511即abbbaa
结巴去重案例
String content = "我...我要.....学学学学.......编程Java!";
String regStr = "\\.+";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
//1. 去掉所有的.
content = matcher.replaceAll("");
System.out.println(content);
//2. 去掉重复的字 使用(.)\\1+ 这样就是匹配至少出现2次的重复的字
//注意:由于正则表达式发生变化,所以需要重置matcher
pattern = Pattern.compile("(.)\\1+"); //分组的捕获内容记录到$1
matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println(matcher.group(0));
}
System.out.println("去掉.的字符:" + content);
//3. 使用反向引用$1来替换匹配到的内容
content = matcher.replaceAll("$1");
System.out.println("最后的字符为:" + content);
// 使用一条语法,去掉重复的字,
content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
System.out.println("使用一条语法去掉重复的字为:" + content);.
//使用字符串的replaceAll直接进行正则表达式替换 将JDK1.4 JDK1.3替换为JDK
String content = "1s5a3fg1564 JDK1.3g srgJDK1.4";
content = content.replaceAll("JDK1(\\.3|\\.4)","JDK");
System.out.println(content);
//验证一个手机号,必须以138 139开头
// 直接使用字符串的matches方法,也是使用正则方法。
content = "13588889999";
System.out.println(content.matches("13(8|9)\\d{8}"));
//字符串的spilt方法
//要求按照# - ~ 数字来分割
content = "hello#abc-jack12smith~北京";
String[] spilt = content.split("#|-|~|\\d+");
for(String s:spilt)
System.out.println(s);
//判断邮箱是否OK合格
String content = "";
boolean ans = content.matches("[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+");
// 判断是否为整数或小数。
boolean ans = content.matches("^[-+]?([1-9]\\d*|0)(\\.\\d+)?$")
引用类型的放在方法区中的常量池
成员变量 = 属性 = field(字段)
访问修饰符: 控制属性的访问范围,共4种:public, protected, 默认,private
Person p1 = new Person();
// p1是对象名,也称对象引用
// new Person()创建的对象空间(包括数据)才是真正的对象
// 对象的默认属性值和数组一样,char是\u0000 String是null,其他的都是0
//创建对象的两种方式
//1.先声明再创建
Cat cat; //此时并没有创建空间。
cat = new Cat();
// 2. 直接创建
Person p1 = new Person(); //在堆中开辟一个空间
此时堆中有一个空间,内有两个 空间是age和name,都是初始值0和null
赋值之后小明在常量区创建一个小明的引用类型
然后将p2指向p1。此时p1和p2指向堆中同一片空间
内存分配机制:堆栈
方法的使用原理
** 编写类AA 有一个方法,判断一个数是奇数odd还是偶数even。返回boolean**
//
import java.util.Scanner;
public class MethodExercise01 {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
AA a = new AA();
System.out.println(num + "是否是?" + a.isEven(num));
scanner.close();
}
}
class AA {
public boolean isEven(int n){
if(n%2==0)
return true;
return false;
}
}
要写测试类,就是写main函数的类!!!!
删除所选行:Ctrl + d
克隆行:Ctrl + Alt + 向下光标
Alt + /
Ctrl + /
第一次是添加注释,第二次是取消注释Alt + Enter
Ctrl + Alt + L
Alt + insert
选择构造函数Ctrl + h
I
itit
new Scanner(System.in).var => Scanner scanner = new Scanner(System.in);
Ctrl + Alt + T
try-catch什么的。Ctrl+Shift+加号(回退左边的), 减号
: 展开或折叠方法体import java.util.Arrays;
Arrays.sort(a); // 库函数对数组直接排序
访问修饰符 modifer:
类只有public和默认可以修饰
封装步骤:
继承细节:
this.cal()
(这种方法等价于cal()
).调用父类的方法:super.cal()
this()
方法从从本类开始一直往父类找,并不是只找本类。this方法也可以访问到父类的变量和方法,子类没有就往父类找class father{
String name = "jack";
father(String s){
this.name = name;
}
}
class son extends father{
String name = "Rose";
son(String s){
super(s);
}
}
main中:
son("John");
这个方法是将John赋值给father类中的name而不是son类中的name。
class B{
B(){
// 无访问修饰符的变量。
this("ABC"); //调用B(String str)方法
System.out.println("b");
}
B(String str){
System.out.println("b name" + str);
}
}
方法重写Override
如何继承父类的属性? 在子类中使用?
public Student(String name, int age, int id, int score){
super(name, age); //继承父类的name, age。 这里会调用父类构造器 父类要有这样的构造器
this.id = id;
this.score = score;
}
子类中如何调用父类的属性或方法,直接使用?
如果父类的属性是private的,只能使用get方法。如果要重写父类的方法,可在子类里直接调用父类的方法:super.方法()
多态
Animal animal = new Dog()
Animal animal = new Dog(); // 编译类型是animal,运行类型是Dog
animal = new Cat(); // 将运行类型改为Cat
1.多态的向上转型(父类的引用指向子类的对象)
父类类型 引用名 = new 子类类型();
2.多态的向下转型
把指向子类对象的父类引用,转化为指向子类对象的子类引用。
将父类的对象引用转为子类的对象引用。如果这个引用不是父类类型或其子类的,则无法向下转型。向下转型时要判断引用是否为父类类型或其子类的
子类类型 引用名 = (子类类型) 父类引用
Cat cat = (Cat) animal; // 将父类的引用转换为子类的
// 错误示例
Animal animal = new Cat();
Cat cat = (Cat) animal; // 向下转型,此时cat和animal都指向Cat类
Dog dog = (Dog) animal // 报错。animal指向Cat类,不能转为Dog类。
Person person = new Student(); //向上转型,
Student student = (Student) person; //向下转型
//下面是错误示例:
Person person = new Person();
Student student = (Student) person; //向下转型 错误!
// person本来是指向父类对象的父类引用而不是指向子类对象的父类引用,所以无法向下转型。
属性没有重写之说,属性的值看的编译类型 即看= 左边的
instanceOf 用于判断对象的运行类型是否为XX类型或XX类型的子类型.
可以直接用getClass()方法查看对象的运行类型
属性只看编译类型,方法要看运行类型。从子类到父类依次去找。
Java的动态绑定机制★★★★★
多态的应用
多态数组
数组的定义为父类类型,里面保存的元素类型为子类类型
父类类型的引用可以指向子类类型的对象
// 要调用子类中不同的方法的实现:向下转型
// 如果仅调用子类中相同方法,直接调用就可。向上转型在调用方法和属性时从子类开始找。
Person[] persons = new Person[3];
persons[0] = new Person("龙岗区", 22);
persons[1] = new Student("我需要", 22, 20, 100);
persons[2] = new Teacher("和视频", 40, 10000000);
for(int i=0; i< persons.length; i++){
if(persons[i] instanceof Student){
Student student = (Student) persons[i]; // 向下转型 本来是向上转型的,无法使用子类特有成员方法。 所以要向下转型来使用子类特有的成员方法。
System.out.println(student.learn());
} else if(persons[i] instanceof Teacher){
Teacher teacher = (Teacher) persons[i];
System.out.println(teacher.teach());
}else if(persons[i] instanceof Person){
System.out.println(persons[i].say());
}
}
多态参数
向下转型并访问子类特有方法:
Employee e = new Employee();
// 1. 先转型,在访问
Executive manager = (Executive) e;
return manager.manage();
// 2. 转型和访问一起实现
((CEmployee) e).work(); //(CEmployee) e 是向下转型
Object类中常用方法
equals()
hashCode() // 返回该对象的哈希码值
getClass()
equals
==和equals的区别:
练习1:
// 重写Person类继承的Object类中的方法:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if(obj instanceof Person){
Person p = (Person) obj; //将Object类向下转型到Person类
return p.name.equals(this.name)&&p.age==this.age;
}
return false;
}
hashCode
toString
将int, double转为toString
int a = 5;
double b = 0.5;
sout(Integer.toString(a));
sout(Double.toString(b));
断点调试
java对象数组在使用时,要每个重新赋值。
houses[idx] = new House(); // 每一个数组的元素都要重新设置。
类变量
类变量,也叫静态变量,用static修饰。
该变量最大的特点就是会被该类所有的对象实例共享
类变量可以通过类名.类变量名
或对象名.类变量名
来访问
静态方法(类方法)
当方法中不涉及任何与对象相关的成员时,则可以将方法设计成静态方法,提高开发效率。
代码块
代码块又称初始化块,属于类中的成员,类似于方法,封装于方法体内,通过{}包围起来。
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显示调用,在加载类或创建对象时隐式调用。
// 语法:
[修饰符]
{
}; //;可以省略
//eg:
{
System.out.println("电脑屏幕打开");
System.out.println("广告开始");
System.out.println("电影正式开始");
}
注意:
优点:
细节:
类加载时做的事情:
小结:
创建一个对象时,在一个类中的调用顺序是:(重点,难点)
① 调用静态代码块和静态属性初始化。(多个静态的按定义的顺序调用)
② 调用普通代码块和普通属性的初始化。(多个普通的按定义的顺序调用)
③ 调用构造方法。
注: 上面的静态方法和普通方法在类中调用该方法时才会使用。
父类的初始化
构造器的最前面其实隐含了super()和调用普通代码块。
class A{
public A(){
// 这里有隐藏的执行要求
// 1.super()
// 2.调用普通初始代码块
// 3. 构造器的内容。
}
}
创建一个子类对象(继承关系时),其静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法调用顺序:
① 父类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
② 子类的静态代码块和静态属性初始化(优先级一样,按定义顺序执行)
③ 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
④ 父类的构造方法
⑤ 子类的的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
⑥ 子类的构造方法
单例就是在整个运行过程中,某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。
单例设计模式有两种方式:1. 饿汉式 2.懒汉
步骤【饿汉式】:
注:因为要在不创建对象实例的前提下得到一个对象实例,所以必须new静态对象,提供静态方法。
class Cat {
// 饿汉式
private String name;
private static Cat cat = new Cat("Tom"); //在类中创建静态private对象
// 构造器私有化
private Cat(String name) {
this.name = name;
}
public static Cat getInstance(){
// 静态方法返回对象
return cat;
}
}
class Cat {
// 懒汉式
private String name;
private static Cat cat; //创建对象引用,但不创建
private Cat(String name) {
this.name = name;
}
public static Cat getInstance(){
if(cat == null)
cat = new Cat("Tom"); //在需要得到对象时才去引用
return Cat;
}
}
懒汉式VS饿汉式
可以修饰类,属性,方法和局部变量。
public final double MAX_RATE = 0.08
当父类的某些方法需要声明但有不确定如何实现时,可以将其声明为抽象方法,则这个类就是抽象类。
// 抽象类示例:
abstract public void eat();
用abstract关键字来修饰一个类时,这个类就叫抽象类。
访问修饰符 abstract 类名{
}
用abstract关键字来修饰一个方法时,这个方法就是抽象方法。
// 抽象方法没有方法体
访问修饰符 abstract 返回类型 方法名(参数列表);
抽象类的价值更多在于设计,是设计者设计好后,让子类继承并实现抽象类。
抽象类不能被实例化。
抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法。
一旦类包含了abstract方法,则这个类必须声明为abstract。
abstract只能修饰类和方法,不能修饰其他的。
如果一个类继承了抽象类,则他必须实现抽象类的所有抽象方法,除非他自己也声明为abstract类。
抽象方法不能用private,final,static修饰。
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把方法写出来。
interface 接口名{
// 属性
// 抽象方法
}
class 类名 implements 接口{
// 自己属性
// 自己方法
// 必须实现的接口的抽象方法
}
小结: 接口是更抽象的抽象的类。抽象类里的方法可以有方法体,接口里的所有方法都没有方法体。接口体现了程序设计的多态和高内聚低耦合的思想。
public static final
修饰符。接口名.属性名
Phone phone = new UsbInterface()
(多态)接口vs继承
一个类的的内部又完整的嵌套了另一个类结构被嵌套的类被称为内部类inner class,乞讨其他类的类称为外部类outer class。内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
如果定义在局部位置(方法中/代码块):1. 局部内部类 2. 匿名内部类。
定义在成员位置:1. 成员内部类 2. 静态内部类。
// 基本语法:
class Outer{
class Inner{
}
}
class Other{
}
内部类的分类:
定义在外部类局部位置上(通常在方法内):
定义在外部类的成员位置上:
class A{
public void fun(){
class B{
private final String name = "刘广琦";
public void show(){
System.out.println("局部内部类B的name=" + name);
System.out.println("外部类A的name=" + A.this.name);
}
}
B b = new B(); // 在主类体内先创建局部内部类对象
b.show(); // 调用局部内部类方法
}
}
匿名内部类和接口:通过创建一个实现接口的匿名类的实例,从而间接地使用接口
匿名内部类通常用于重写已有的类或接口的方法。
new 类或接口(参数列表) {
};
匿名内部类当作参数
// 例1
// 示匿名内部类
public class AnonymousClass {
public static void main(String[] args) {
// 直接使用匿名内部类。
// 匿名内部类可以当作实参直接传递,简介高效
f1(new IL(){
@Override
public void show() {
System.out.println("这是一副名画~~~~");
}
});
// 传统方法 先写一个类实现IL接口,再用这个类
f1(new Picture());
}
//静态方法 形参是接口类型
public static void f1(IL il){
il.show();
}
}
interface IL {
void show();
}
//不使用匿名内部类:类->实现 IL => 编程领域 (硬编码:专门写一个类来实现某个仅使用一次的功能)
class Picture implements IL {
@Override
public void show() {
System.out.println("这是一副名画 XX...");
}
}
// 例2
public class Telephone {
public static void main(String[] args) {
Cellphone cellphone = new Cellphone();
/*
* 传递的是实现了Bell接口的匿名内部类
* 重写了ring方法,即接口的ring方法
* alarmclock的参数Bell bell的编译类型是最初的Bell接口
* 运行类型是新实现的匿名内部类
*/
cellphone.alarmclock(new Bell() {
@Override
public void ring() {
System.out.println("懒猪起床了");
}
});
}
}
public class Cellphone{
public void alarmclock(Bell bell){
bell.ring();
}
}
interface Bell{
public void ring();
// 例3
package enum_;
public class homework04{
public static void main(String[] args) {
Cellphone cellphone = new Cellphone();
cellphone.testWork(new Calculator() {
//重写Calculator()接口,变成类
@Override
public double work(double a, double b) {
return a + b;
}
}, 10, 20);
}
}
interface Calculator {
public double work(double a, double b);
}
class Cellphone{
public void testWork(Calculator calculator, double a, double b){
double res = calculator.work(a, b);
System.out.println("计算后的结果是" + res);
}
}
成员内部类是定义在外部类的成员位置,且没有static修饰。
可以直接访问外部类的所有成员,包含私有的。
可以添加任意访问修饰符(public, protected, 默认, private),因为它的地位就是一个成员
作用域:整个类。
成员内部类访问外部类成员:【直接访问】
外部类访问成员内部类:【先创建对象,在访问】
外部其他类访问成员内部类:【2种方式】
//外部其他类使用成员内部类的方法
// 法一 先创建父类,再dot 子类创建子类
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.hi(); // 调用hi方法
// 法二 在外部类中编写一个方法返回内部类对象
Outer.Inner inner1 = outer.getInstance();
inner1.hi(); // 调用hi方法
class Outer{
class Inner{
// 成员内部类
public void hi(){
System.out.println("hi()方法...");
}
} //内部类
public Inner getInstance(){
return new Inner();
}
package enum_;
public class homework07 {
public static void main(String[] args) {
Car car = new Car(39);
Car car1 = new Car(41);
Car car2 = new Car(-14);
Car.Air air = car.new Air(); // 直接创建子类对象
Car.Air air1 = car1.new Air();
car.getAir().flow(); //使用方法返回一个内部类Air对象
car1.getAir().flow();
car2.getAir().flow();
}
}
class Car{
private int temperature;
public Car(int temperature) {
this.temperature = temperature;
}
public int getTemperature() {
return temperature;
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
class Air{
public void flow(){
if(temperature>40){
System.out.println("吹冷气");
}
else if(temperature < 0){
System.out.println("吹暖气");
}
else{
System.out.println("关闭空调");
}
}
}
// 提供一个方法,返回Air对象
public Air getAir(){
return new Air();
}
}
静态内部类是定义在外部类的成员位置,且有static修饰。
可以直接访问外部类的所有静态成员,包括私有的。但不能访问非静态成员。
可以添加任意访问修饰符(public,protected,默认,private),因为其地位就是一个成员
作用域:整个类
静态内部类访问外部类(只能访问静态):【直接访问】
外部类访问静态内部类:【先创建对象,在访问】
外部其他类访问静态内部类:
// 方法一 因为静态内部类,所以可以通过类名直接访问,不用先创建外部类实例
Outer.Inner inner = new Outer.Inner();
inner.say(); //调用静态内部类say方法
// 方法2 编写一个方法,返回静态内部类的对象实例。
Outer outer = new Outer(); //创建外部类对象实例
Outer.Inner inner = outer.getInner();
class Outer{
static class Inner{
//...
}
public Inner getInner() {
return new Inner();}
}
如果外部类和静态内部类的成员重名时,静态内部类访问时,遵循就近原则,如果想访问外部类的成员,使用【外部类名.成员去访问】
多个枚举类对象用逗号分隔,且要将枚举类对象放在最前面
enum常用方法应用实例:
// 示例
enum Season{
SPRING("春天","温暖"), //等价于public static final Season SPRING = new Season("春天", "温暖")
SUMMER("夏天", "炎热"),
AUTUMN("秋天","凉爽"),
WINTER("冬天","寒冷");
private String name;
private String desc;
private Season(){
}
private Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
//举例2
public class Enumeration01 {
public static void main(String[] args) {
Week[] weeks = Week.values();
for(Week week : weeks){
// 增强for循环
System.out.println(week); //这里输出的实际为toString方法中的返回值
}
}
}
enum Week{
MONDAY("星期一"), TUESDAY("星期二"),
WEDNESDAY("星期三"), THURSDAY("星期四"),
FRIDAY("星期五"), SATURDAY("星期六"), SUNDAY("星期日");
private String name;
private Week(String name){
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
// 使用switch匹配枚举类对象
package enum_;
public class homework08 {
public static void main(String[] args) {
//枚举值在switch中的使用
Color green = Color.GREEN;
green.show();
switch (green){
case RED:
System.out.println("匹配到红色");
break;
case BLUE:
System.out.println("匹配到蓝色");
// ...
}
}
}
enum Color implements Interface{
RED(255,0,0),
BLUE(0,0,255),
BLACK(0,0,0),
YELLOW(255,255,0),
GREEN(0,255,0);
private int redValue;
private int greenValue;
private int blueValue;
Color(int redValue, int greenValue, int blueValue) {
this.redValue = redValue;
this.greenValue = greenValue;
this.blueValue = blueValue;
}
@Override
public void show() {
System.out.println("redValue=" + redValue);
System.out.println("greenValue=" + greenValue);
System.out.println("blueValue=" + blueValue);
}
}
interface Interface {
public void show();
}
@Override 重写
@interface 表示一个注解类
@Target 修饰注解的注解,称为元注解。
@Deprecated 用于表示某个程序元素已过时。修饰某个元素
@SuppressWarnings: 抑制编译器警告
JDK 的元 Annotation 元注解
异常的第一个案例
package exception_;
public class Exception01 {
public static void main(String[] args) {
int num1 = 10;
int num2 = 0;
try {
int res = num1 / num2;
} catch (Exception e) {
System.out.println("出现异常的原因=" + e.getMessage());
}
System.out.println("程序继续运行");
}
}
Integer.parseInt(String s) 将字符串s转为int类型
public static void main(String[] args) {
String str = "132456l";
try {
int a = Integer.parseInt(str);
System.out