目录
一、代码块
- 初始化块,属于类的一个成员,它是将一些逻辑语句封装在方法体中 通过{}包裹
- 类的内部结构:属性、方法、构造器、代码块、内部类
1. 局部代码块
局部代码块是定义在方法或语句中。
特点:
以”{}”划定的代码区域,此时只需要关注作用域的不同即可。
方法和类都是以代码块的方式划定边界的。
class Demo{
public static void main(String[] args) {
{
int x = 1;
System.out.println("普通代码块" + x);
}
int x = 99;
System.out.println("代码块之外" + x);
}
}
结果:
普通代码块1
代码块之外99
2. 构造代码块
构造代码块是定义在类中成员位置的代码块。
特点:
优先于构造方法执行,构造代码块用于执行所有对象均需要的初始化动作。
每创建一个对象均会执行一次构造代码块。
public class Person {
private String name;
private int age;
//构造代码块
{
System.out.println("构造代码块执行了");
}
Person(){
System.out.println("Person无参数的构造函数执行");
}
Person(int age){
this.age = age;
System.out.println("Person(age)参数的构造函数执行");
}
}
class PersonDemo{
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person(23);
}
}
3. 静态代码块
静态代码块是定义在成员位置,使用static修饰的代码块。
特点:
它优先于主方法执行、优先于构造代码块执行,当以任意形式第一次使用到该类时执行。
该类不管创建多少对象,静态代码块只执行一次。
可用于给静态变量赋值,用来给类进行初始化。
public class Person {
private String name;
private int age;
//静态代码块
static{
System.out.println("静态代码块执行了");
}
}
总结:
局部代码块:定义在方法中的,用来限制变量的作用范围。
构造代码块:定义在类中方法外,用来给对象中的成员初始化赋值。
静态代码块:定义在类中方法外,用来给类的静态成员初始化赋值。
4. 面试题:
- 当没有继承关系,就一个类,静态块---实力块---构造器
- 当有继承关系,父类静态块---子类静态块---父类实例块(局部)---父类构造器---子类实例块---子类构造器
- 父优于子,静态优于非静态
二、static(静态)
当创建一个类有以下代码:
static String room;
- 一旦使用了关键字static,那么这样的内容不再属于对象自己,而属于所在的类;
- 当所在类被new出来之后,它不再需要用对象去.出来;
调用:
类名.room;//使用这个内容直接用所在类.出来
例如:
public class Test{
public static void main(String[] arge){
//Student stu=new Student();
System.out.println(Student.room);
}
}
public class Student{
static String room="项目组1";
}
上面代码输出结果为:项目组1
详解:
以上代码中Student stu=new Student();是被注释的,也就是说stu这个对象并没有创建出来,而room是直接用类名.出来并输出。
或者,也可以把stu这个对象创建出来,用stu这个对象.room也是可以的,但是不赞成这样使用,因为这样的写法再被编译后也会编译成类名.room。
如果没有static关键字,那么必须创建对象,然后通过对象才能使用;
如果有了static关键字,那么不需要创建对象,直接通过类名称来使用。
内存图如下:
静态的变量存在于方法区。静态结构不会被回收。
不属于某一个实例对象,只存在于方法区。调用静态结构,直接用类名.的结构。
注意事项:
1、静态不能直接访问非静态
原因:因为在内存中是“先”有的静态内容,“后”有的非静态内容
2、静态方法中不能使用this
原因:this当前对象,通过谁调用方法,谁就是当前的对象
普通内部类和静态内部类的区别
1.声明方式
要实例化一个普通内部类,首先需要实例化其所在的外部类,然后再实例化内部类;而静态内部类可以直接声明。
2.可以定义或访问的变量类型
<1>普通内部类内不能声明static类型的变量,而静态内部类内可以;
<2>普通内部类实例化后持有外部类对象的引用,在普通内部类内部可以访问外部类中的变量和方法;静态内部类实例化后不持有外部类对象的引用,在静态内部类中不能访问外部类中的变量和方法。
3.外部类对内部类的访问方式
外部类中的静态方法不能创建普通内部类对象,可以创建静态内部类对象;可以将静态内部类与普通内部类近似为静态变量与普通变量,静态方法不能访问普通变量。
4.总结
总而言之,从耦合程度上来讲,普通内部类与外部类的耦合程度很高,静态内部类与外部类的耦合程度很低。可以近似地说,静态内部类除了定义在一个类的内部,几乎与外部类没有差别。
三、设计模式:
1. 单例模式:一个类只有一个实例。
思路:
1.别人不能new,构造器私有化,不能在类的外部通过new去实例化
2.在该类的内部产生一个唯一的实例对象.
2. 饿汉式单例模式
不管以后会不会使用到该实例对象,先创建了再说,很着急的样子。
实现的办法就是直接new实例化。
public class Ch01 {
private static Ch01 ch01=new Ch01();
private Ch01(){}
public static Ch01 getInstance(){
return ch01;
}
}
3.懒汉式:(延迟加载)
- 什么时候调用getInstance方法,什么时候new
- 在多线程环境中完全错误,根本不能保证单例的状态
- 到时候会《加锁》
public class Ch02 {
//把自身实例化对象设置成一个属性,现在没有赋值
private static Ch02 ch02;
//构造器私有化
private Ch02(){
}
public static Ch02 getInstance(){
if (ch02==null) {
ch02 = new Ch02();
}
return ch02;
}
}
4. 内部类实现单例
也是懒汉式的一种,没有线程问题
结合了饿汉式和懒汉式的优点:
只要不调用getInstance方法,就不会使用内部类
内部类一但使用一次就会初始化一次,以后会一直用的时候INSTANCE
public class Ch03 {
//私有化构造器
private Ch03(){
}
public static Ch03 getInstance(){
return Singleton.INSTANCE;
}
public static class Singleton{
private static final Ch03 INSTANCE=new Ch03();
}
}
5. 设计模式
设计模式是人们为软件开发中抽象出可重复利用的解决方案。
软件开发工程师之间沟通的“行话”。
面向对象的设计原则。
1、开闭原则 (Open ClosePrinciple)
对扩展开放,对修改关闭。 (继承,实现接口)
我们可以通过“抽象约束,封装变化”来实现开闭原则。
通过接口或者抽象类为软件定义一个相对稳定的抽象层。
将相同的可变因素封装在相同的具体实现类中。派生一个实体类就可以了
2、里氏代换原则
子类继承父类时,除了添加新的方法完成新增的功能外,尽量不要重写
3、依赖倒转原则
要面向接口编程,不要面向实现编程。
米 a、每个类尽量提供接口或抽象类,或者两者兼备米 b、变量的类型声明尽量是接口或者是抽象类水 c、任何类都不应该从具体类派生
d、使用继承时,要遵循里氏代换原则。
4、接口隔离原则
使用多个隔离的接口。
5、迪米特法则
6、合成复用原则
7、单一原则:一个类只做 件事
四、箭头函数
箭头函数:JDK8的新特性 I
函数式接口:如果一个接口只有一个抽象方法,这个接口就称为函数式接口。可以用注解@FunctionalInterface标识。
1、有参数,有返回值。
(i,j)->
return i+ j;
如果方法体只是一句返回值(i,j)-> i+j
2、有参数,无返回值
(i,j)->{
//方法体 }
如果方法体只有一句话(i,j)-> 方法体的一句话
3、无参数
()->{
方法体 }
这个结构可以分为三部分
第一部分,小括号包裹形参类型不要
第二部分,->
第三部分,->方法体
()->System.out.println("重写的show方法...")当重写的方法体只有一句话时,可以精简到这种
test(()-> system.out.println("重写的show方法..."));
五、实例
public class HuangDi {
private HuangDi() {
}
private static HuangDi instance = null;
private static String name;
public static String getInstance(String name) {
if (instance == null) {
instance = new HuangDi();
}
return name;
}
static class Test {
public static void main(String[] args) {
System.out.println("创建1号皇帝对象");
String name1=HuangDi.getInstance("name=“秦始皇”");
System.out.println("创建2号皇帝对象");
String name2=HuangDi.getInstance("name=“秦始皇”");
System.out.println("创建3号皇帝对象");
String name3=HuangDi.getInstance("name=“秦始皇”");
System.out.println("三个皇帝对象依次是:");
System.out.println(name1);
System.out.println(name2);
System.out.println(name3);
}
}
}
六、心得体会
今天的值是比较零散,不过还是好理解的!!!