一. 代码块(了解)
(一)概述
1、使用大括号包起来的一段代码。放在不同的位置,有不同的名称,有不同的作用,有不同的执行时机。
2、分类:
局部代码块
构造代码块
静态代码块
同步代码块(多线程)
(二)局部代码块
1、位置:定义在方法中的代码块
2、作用:
限定变量的生命周期
在局部代码块中【声明】的变量,只能在局部代码块的范围内使用,一旦出了局部代码块的大括号,变量就不能继续使用了。
缩短局部变量的生命周期,及时的释放内存空间提升代码的运行效率
3、注意事项:
(1) 代码块可以使用外部的所有资源
(2) 如果是在局部代码块中修改了局部代码块外声明的变量,局部代码块结束之后,并不会消除局部代码块对这个变量的修改。
public class Demo01_局部代码块 { public static void main(String[] args) { int i = 10; // 局部代码块: 作用, 限定 定义在局部代码块中变量作用范围 // 优势: 不仅仅是范围的限定,也是变量在内存中存储时间的限定,例如y变量,如果局部代码块执行完毕, y就变成了一个无法再使用的变量,很快就会被JVM回收掉 { int y = 20; System.out.println(y); // 如果是局部代码块之外变量使用,不受局部代码块限制 i = 88; } // System.out.println(y); System.out.println(i);// 88 } }
(三)构造代码块
1、位置:定义在类中方法外【成员变量位置】
2、作用:
(1) 创建对象的时候给对象的属性值显性赋值
(2) 提取本类构造方法中的共性内容实现
3、构造代码块的执行说明:
1、在创建对象的时候执行,由jvm默认调用
2、在构造方法执行之前,执行
public class Demo02_构造代码块 { int i = 10; String name; // 构造代码块: // 运行时机: 当每次创建对象的同时, JVM虚拟机主动调用构造代码块一次, 并且是在构造方法之前 // 作用: 可以给当前对象中的成员变量进行赋值; 如果当前类型中有多个构造方法, 并且这些构造中有相同的处理逻辑 // 这些逻辑可以提升到构造代码块中完成 { name = "张三"; System.out.println("构造代码块运行了"); System.out.println("我是构造方法"); } public Demo02_构造代码块(){ // System.out.println("我是构造方法"); } public Demo02_构造代码块(int i){ this.i = i; // System.out.println("我是构造方法"); } public static void main(String[] args) { Demo02_构造代码块 demo = new Demo02_构造代码块(); System.out.println(demo.name); Demo02_构造代码块 demo1 = new Demo02_构造代码块(99); } }
(四)静态代码块(一定掌握)
1、格式:
static {
静态代码块的内容
}
2、位置:类中方法外
3、作用:
(1) 给类的静态变量赋值
(2) 用来加载只需要加载一次的资源【例如: 加载数据库驱动】
4、执行特点:
(1) 随着类的加载而执行
(2) 静态代码块只执行一次
(3) 执行的时机最早:早于所有的对象相关内容
public class Demo03_静态代码块 { int i; static int w; // 静态代码块: // 1. 可以给类型中的静态成员变量进行赋值 // 2. 静态代码块运行时机: 因为静态都属于类, 因此在当前类进入内存时候(进入方法区),JVM虚拟机主动调用 // 静态代码块一次 // 3. 静态代码块使用场景: 如果有代码只需要执行一次, 并且是在所有其他代码运行之前就执行, 那么这些逻辑 // 可以设计在静态代码块中 // 举例: 数据库,持久性的存储数据; 需要在交易开始之前, 保证数据库连接成功的(登录数据库,读取数据库登录时用户名和密码) // 连接数据库的过程就可以设计在静态代码块中 static{ // i = 10; 静态中不能直接使用非静态 w = 99; System.out.println("我是静态代码块"); } public static void main(String[] args) { System.out.println(Demo03_静态代码块.w); Demo03_静态代码块 dmo = new Demo03_静态代码块(); } }
二. 内部类(了解)
(一) 概述
1. 定义在一个类中的另一个类就叫做内部类
举例:在一个类A的内部定义一个类B,类B就被称为内部类
2. 格式:
public class Outer { // 外部类
public class Inner { }// 内部类
}
人类: 定义成Person, 人类组成很复杂, 身体器官: 心脏, 肝, 肾...
心脏: 血压, 心跳, 颜色, 控制身体机能
3. 分类: 根据定义的位置不一样以及是否有名分为了不同的内部类,具体分类如下:
1) 成员内部类
2) 局部内部类
3) 匿名内部类(掌握)
4. 访问特点:
内部类可以直接访问外部类的成员,包括私有成员
外部类要访问内部类的成员,必须创建对象
(二) 普通成员内部类
1. 定义位置: 在类中方法外,跟成员变量是一个位置
1. 外界创建成员内部类格式
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:Outer.Inner oi = new Outer().new Inner();
2. 访问方式:
(1) 内部类可以直接访问外部类的所有成员,包括私有成员
(2) 外部类访问内部类的成员,必须先创建内部类对象
public class Body { int height = 80; public void test(){ System.out.println("我是test"); } // 普通成员内部类 class Heart{ String color = "红色"; int jump = 100; int height = 999; public void show(){ // 1. 内部类中可以直接使用外部类中的成员(成员变量, 方法) System.out.println(color + "颜色的心脏,每分钟跳" + jump + "下,血压为:" + height + "--" + new Body().height); test(); } } // 2. 外部类如果想使用内部类成员, 需要创建出一个内部类对象 public void useHeart(){ System.out.println(height); Heart h = new Heart(); System.out.println(h.color); System.out.println(h.jump); h.show(); } }
public class TestInnerClass { public static void main(String[] args) { // 1. 测试普通成员内部类使用 Body b = new Body(); b.useHeart(); System.out.println("--------------------------------"); // 2. 测试普通成员内部类对象在其他类中创建 // 外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象(); Body.Heart h = new Body().new Heart(); // Heart h1 = new Heart(); System.out.println(h.color); System.out.println(h.jump); System.out.println(h.height); h.show(); } }
(三) 私有的成员内部类
1、也是一个成员内部类,在成员内部类前面加上一个private关键字
2、访问方式:
(1) 在外部类以外,不能直接访问外部类中的私有成员内部类
(2) 可以在外部类中,定义一个访问私有成员内部类的公有方法,让外界可以调用公有方法,间接的访问外部类中的私有成员内部类。
public class Body1 { private int height = 80; public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public void test(){ System.out.println("我是test"); } // 普通成员内部类 private class Heart1{ String color = "红色"; int jump = 100; int height = 999; public void show(){ // 1. 内部类中可以直接使用外部类中的成员(成员变量, 方法) System.out.println(color + "颜色的心脏,每分钟跳" + jump + "下,血压为:" + height + "--" + new Body1().height); test(); } } // 2. 外部类如果想使用内部类成员, 需要创建出一个内部类对象 public void useHeart1(){ System.out.println(height); Heart1 h = new Heart1(); System.out.println(h.color); System.out.println(h.jump); h.show(); } }
public class TestInnerClass { public static void main(String[] args) { // 3. 测试私有成员内部类: 通过间接方式访问私有成员内部类 Body1 b1 = new Body1(); b1.useHeart1(); } }
(四) 静态的成员内部类
1、也是一个成员内部类,在成员内部类前面加上一个static关键字
2、访问方式:
(1) 成员内部类是外部类的静态成员,所以可以通过外部类名.内部类名的方式直接访问,而不需要创建外部类的对象
(2) 静态内部类中的非静态成员,需要将所在的内部类对象创建出来之后,才能被调用。
总结:一个类是否需要创建对象,不取决于该类本身是否是静态,而取决于要访问
的成员是否是静态
3、静态成员内部类的对象创建格式:
外部类名.内部类名 内部类对象名 = new 外部类名.内部类名();
public class Body2 { // w表示每天喝多少升水 static int w = 2; // 静态成员内部类 // 是否需要创建对象调用成员: 如果这个成员是非静态的, 那么创建对象; 如果这个成员是静态成员, 那么不需要创建对象, 类名.直接调用 static class Shen{ int day = 1; static int wc = 8; public void show(){ System.out.println(day + "天喝了" + w + "升,应该去卫生间"+ wc + "次"); } } }
public class TestInnerClass { public static void main(String[] args) { // 4. 测试静态成员内部类: // 1) 调用静态成员内部类中的静态成员变量 System.out.println(Body2.Shen.wc);// 8 // 2) 调用静态成员内部类中非静态成员变量 // 静态成员内部类对象创建方式: // 外部类名.内部类名 对象名 = new 外部类名.内部类名(); Body2.Shen sh = new Body2.Shen(); System.out.println(sh.day);// 1 sh.show();// 1天喝了2升,应该去卫生间8次 } }
(五) 局部内部类
1. 定义位置: 局部内部类是定义在方法中的类
2. 访问方式:
(1) 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
(2) 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public class Demo_局部内部类 { public static void main(String[] args) { breath(); } public static void breath(){ // 1. count作为局部变量不能单独获取到, 只能跟着breath方法运行使用 int count = 10; // 2. 局部内部类, 与局部变量类似,只能在方法中定义使用 class Fei{ String color = "black"; public void show(){ System.out.println("每天吸" + count + "跟烟,总有一天肺就会变成" + color); } } // 3. 局部变量,直接在方法中创建对象使用 Fei f = new Fei(); System.out.println(f.color); f.show(); } }
三. final关键字
1、final是一个关键字 含义:最终的,最后的,表示不能再改变的。
2、final关键字:可以修饰类、方法、变量
3、修饰类:
(1) 表示一个最终类,表示不能有子类,【不能被其他类继承】
(2) 一旦一个类型不能被继承,那么其中所有的方法都不能被重写
(3) 不影响当前类的方法被调用
4、修饰方法:
表示一个最终方法,【该方法不能被重写】
5、修饰变量:
(1) 表示一个最终变量,该【变量变成了常量】,就只能赋值一次
(2) 当前项目中,常用的常量一般都定义在一个类的成员位置,甚至专门定义一个常量类,常量命名规范: 所有单词全大写, 多个单词之间使用_进行分隔了,举例: SCHOOL_NAME PI
(3) 定义常量的好处:见名知意,容易理解;可维护性高
final修饰类代码
// final修饰的类没有子类 public final class FinalClass { int i = 10; static int w = 20; public void fun(){ System.out.println("我是final类中的fun方法"); } }
/*public class FinalClassSub extends FinalClass{ // 报错 }*/
final修饰方法:
public class FinalMethod { public final void eat(){ System.out.println("我是final修饰的吃饭功能, 不能被继承,但是可以直接使用"); } }
public class FinalMethodSub extends FinalMethod{ // 子类继承到了父类中的eat方法,但是因为这个方法是final修饰的,只能使用不能重写 /*public void eat(){ System.out.println("我是final修饰的吃饭功能, 不能被继承,但是可以直接使用"); }*/ }
final修饰变量:
public class FinalVariable { // 5. final修饰成员变量: 最好直接赋值(扩展: final修饰成员变量, 必须在创建对象完成之前进行手动赋值) final String name = "张三";// 最推荐 final String sex; public FinalVariable(){ sex = "男"; } int w = 99; // 1. final修饰的变量值不能发生改变, final固定的数据第一次手动赋值 // 2. final修饰的变量称为常量: 所有单词全大写, 多个单词之间_分隔 public static void main(String[] args) { final int I = 10; // 3. final修饰基本数据类型,其数值不能发生修改 // I = 19; // 4. final修饰引用数据类型,那么表示这个引用地址值不能发生改变 final FinalVariable fv = new FinalVariable(); // fv = new FinalVariable(); fv.w = 888; } }
final代码测试类:
public class TestFinal { public static void main(String[] args) { // 1. 测试final修饰的类可以正常使用 FinalClass fc = new FinalClass(); System.out.println(fc.i); System.out.println(FinalClass.w); fc.fun(); // 2. 测试final修饰的方法可以被子类继承, 也可以正常使用 FinalMethodSub fms = new FinalMethodSub(); fms.eat(); FinalMethod fm = new FinalMethod(); fm.eat(); } }
四. 包
1. 包的概述: 用来统一分类管理源代码资源的特殊文件夹;这个文件夹会参与编译。
比如:
com.ujiuye.demo 下的 Person类进行编译的时候类所在的包参与编译,编译后
字节码文件名:com.ujiuye.demo.Person
字节码文件中类名:com.ujiuye.demo.Person【全限定类名】
2. 作用:
(1) 统一管理代码资源
(2) 保证代码编译后类名唯一
(3) 保证代码运行的过程直接进入包找到对应的类
3. 命名规则:
(1) 使用公司域名的反写【保证每一个包路径唯一】
(2) 全部小写
(3) 包名和包名之间使用.隔开
4. 包的声明:
使用关键字 package + 包路径【IDE生成类的时候自动声明】
5. 导包:
同包下:不需要导包
不同包:需要导包【jdk的lang包除外】
使用 import + 包路径
6. 注意:
(1) 没有导包格式之前:使用类的时候不导包的直接使用全限定类名进行使用
比如:java.util.Scanner sc = new java.util.Scanner(System.in);
(2) 使用全限定类名使用类的时候,有点麻烦进行了简化:
使用import关键字进行提取导包进行导包
(3) 作用
可以把同名字的类使用包做一个详细的划分
import com.ujiuye.homework.Phone; public class Test { // com.ujiuye.innerclass.Test // com.ujiuye.block.Test Phone p = new Phone(); // java.lang包下的所有类型可以直接使用, 不需要导包 String str = "abc"; }
五. 权限修饰符
1. 概述: 用来限定资源的使用范围的修饰词汇,就叫做权限(使用)修饰符,不同的符号有不同的限定范围
2. 分类: 从小到大权限罗列
private :私有的 限定范围:本类中使用
默认的 :啥也不写 限定范围:本类和本包中使用
protected :受保护的 限定范围:本类和本包中使用,不同包下的子类内部可以使用
public :公共的 限定范围:没有范围
3. 注意:
1) protected 只修饰方法和变量, 不能修饰类; 保护的是外包子类的内部
2) 总结: 修饰成员变量,为了满足封装特点,使用private修饰;
修饰类,和普通方法功能, 通常使用public修饰
// DefaultClass是默认权限修饰的类: 使用范围本包中使用 class DefaultClass { // 默认权限成员变量 String name = "李四"; // 默认权限方法 void fun(){ System.out.println("我是默认的方法fun"); } }
public class ProtectedClass { protected double height = 175; protected void sleep(){ System.out.println("我是受保护的休眠方法" + height); }
}
public class PublicClass { public String sex = "女"; public void happy(){ System.out.println("happy" + sex); } }
public class TestQuanXian { public static void main(String[] args) { // 1. 默认修饰的类型, 可以在本包中使用 DefaultClass sc = new DefaultClass(); sc.fun(); System.out.println(sc.name); // 2. 受保护权限可以在本包中使用 ProtectedClass pc = new ProtectedClass(); System.out.println(pc.height); pc.sleep(); } }
import com.ujiuye.quanxian.ProtectedClass; public class ProtectedClassSub extends ProtectedClass { // ProtectedClassSub子类继承到了父类中的两个受保护成员 // double height = 175; sleep方法 // 这两个受保护在子类中相当于private使用 public void useProtected(){ System.out.println(height); sleep(); } }
//import com.ujiuye.quanxian.DefaultClass; import com.ujiuye.quanxian.ProtectedClass; import com.ujiuye.quanxian.PublicClass; public class Test { public static void main(String[] args) { // 1. 测试默认权限不能在其他包中使用 // DefaultClass sc = new DefaultClass(); // System.out.println(sc.name); // 2. 测试受保护权限在外包子类之外不能使用 ProtectedClass pc = new ProtectedClass(); // pc.sleep(); ProtectedClassSub pcs = new ProtectedClassSub(); // pcs.sleep(); // System.out.println(pcs.height); // 3. 测试公共修饰的类型可以任意使用, 没有限制 PublicClass pub = new PublicClass(); System.out.println(pub.sex); pub.happy(); } }
修饰符关键字:
private 私有: 封装特性
static 静态: 属于类,跟着类存储在方法区中静态区域中, 就只有一份, 可以被所有对象共享使用
final 最后的, 不可改变的: 修饰类, 修改方法, 修饰变量(常量)
默认权限在类中不写出来, 写了反而代码报错
protected
public
六. 匿名内部类
1、没有名字的内部类
2、匿名内部类的使用前提:
匿名类:继承一个类
匿名类:实现一个接口
1、格式:
new 父类类名或者接口名() {
父类方法的重写或者是接口内容的实现
}
2、本质:
(1) 创建了一个类的子类对象、接口的实现类对象
(2) 更强调关系的一种写法
5、内部类的名称总结:
(1) 如果是有名字的内部类,类名【外部类名$内部类名】
(2) 如果是没有名字的内部类,通过匿名内部类的顺序描述类名,第一个匿名内部类的名称【外部类名$1】,第二个匿名内部类类名【外部类名$2】
public class 匿名内部类 { public static void main(String[] args) { // 1. 匿名内部类可以作为一个类的子类对象存在 /* new 类名(){// 大括号就表示类的子类实现过程 }; */ new Animal(){ @Override public void eat(){ System.out.println("不同动物吃不同的实物"); } }.eat(); } }
代码块总结
1、局部代码块:
- 作用
- 限定 定义在局部代码块的中变量的作用范围
- 优势
- 不仅仅是范围的限定,也是变量在内存中储存时间的限定,(使用完成后,局部代码块外无法再调用 内存回收)
2、构造代码块:在构造方法之前调用,通常用于提取无参构造跟有参构造公共代码
3、静态代码块
1. 可以给类型中的静态成员变量进行赋值
2. 静态代码块运行时机: 因为静态都属于类, 因此在当前类进入内存时候(进入方法区),JVM虚拟机主动调用
静态代码块一次
3. 静态代码块使用场景: 如果有代码只需要执行一次, 并且是在所有其他代码运行之前就执行, 那么这些逻辑
可以设计在静态代码块中
举例: 数据库,持久性的存储数据; 需要在交易开始之前, 保证数据库连接成功的
(登录数据库,读取数据库登录时用户名和密码)
连接数据库的过程就可以设计在静态代码块中
内部类总结
1、普通成员内部类
- 定义位置
- 类中,方法外,跟成员变量同级的位置
- 访问方式
1) 内部类可以直接使用外部类包括的私有属性和方法
2) 外部类访问普通内部类必须通过对象 (类中)
// 1)
Wrapper war = new Wrapper();
Wrapper.Inner inn = war.new Inner();
// 2)
Wrapper.Inner inn2 = new Wrapper().new Inner();
2、私有的成员内部类
- 定义位置 跟普通成员内部类的区别是 前面加上private
- 访问方式:
1) 在外部类以外,不能直接访问外部类中的私有成员内部类
2) 可以在外部类中,定义一个访问私有成员内部类的公有方法,
让外界可以调用公有方法,间接的访问外部类中的私有成员内部类。
3、静态的成员内部类
- 定义位置,也是一个成员内部类,在成员内部类前面加上一个static关键字
- 访问方式:
1) 是外部类的静态成员,所以可以直接类名.静态内部类 使用
2) 如果需要调用 静态类的成员,需要观察静态内部类的成员是否是静态的,
如果是静态的可以直接调用,非静态则需要创建对象调用。
static class StaticInner {
public String name3 = "静态成员内部类-公有局部变量";
private String name33 = "静态成员内部类-私有局部变量";
static String name333 = "静态成员内部类-静态局部变量";
public String getName33() {
return name33;
}
public void staticMethod() { // 静态的成员内部类方法
System.out.println("静态的成员内部类方法");
}
}
Wrapper.StaticInner inn3 = new Wrapper.StaticInner();
System.out.println(Wrapper.StaticInner.name333); // 静态内部类静态属性
System.out.println(inn3.getName33()); // 静态内部类私有属性
System.out.println(inn3.name3); // 静态内部类公有属性
inn3.staticMethod(); // 静态内部公有有方法
4、局部内部类
- 定义位置: 局部内部类是定义在方法中的类
- 访问方式:
1) 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
2) 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public void localFunc() {
String name4 = "局部变量";
class LocalInner{
private String name5 = "局部内部类";
public String getName4() {
return name4;
}
}
// 局部内部类无法在 外部使用,只能在方法中创建对象使用,可以使用方法的局部变量
LocalInner l = new LocalInner();
l.getName4();
}
public class Demo_局部内部类 {
public static void main(String[] args) {
breath();
}
public static void breath(){
// 1. count作为局部变量不能单独获取到, 只能跟着breath方法运行使用
int count = 10;
// 2. 局部内部类, 与局部变量类似,只能在方法中定义使用
class Fei{
String color = "black";
public void show(){
System.out.println("每天吸" + count + "跟烟,总有一天肺就会变成" + color);
}
}
// 3. 局部变量,直接在方法中创建对象使用
Fei f = new Fei();
System.out.println(f.color);
f.show();
}
}