20220727 第五小组 罗大禹 学习笔记
作者:互联网
20220727 第五小组 罗大禹 学习笔记
Java 静态、内部类及代码块
学习重点
1.类的内部结构
2.单例模式
学习心得
今天老师讲的内容较为零散,需要自己好好整理下知识点。
学习内容
Java 静态、内部类及代码块
类的内部结构:
属性、方法、构造器、代码块、内部类
static静态(理解)
可修饰:属性(被修饰后称为类属性),方法(被修饰后被称为类方法),代码块
注意:
用static修饰的结构,不属于任何一个对象
this和super
无论是this还是super,都不可以在静态结构中使用。
静态结构是属于类的,静态结构是优先于对象就存在的。
this和super,必须有对象才能出现。必须得有实例。
static内存解析:
1、静态的变量或者静态方法存在于方法区的。静态的结构不会被垃圾回收。
2、不属于某一个实例对象,只存在于方法区。调用静态结构,直接用类名.的方式。
实例方法和静态方法互相调用:
- 静态方法中不可以直接调用实例方法!!
如果想用,必须对象.方法名 对象.属性名
-
实例方法中可以直接调用静态方法!!
可以直接 ①类名.方法 ② 类名.属性名 进行调用
加载
- 静态的结构的加载,随着类的加载而加载!!!
- 非静态的结构,随着对象的创建而加载!!!
平时用的静态方法
Arrays.toString();
Arrays.sort();
Integer.parseInt();
String.valueOf();
举例说明:
public class Ch03 {
static String name = "啦啦啦";
int age = 20;
String str = "哈哈";
public Ch03(){
show();
}
//实例方法
public void fun(){
show();
}
// 静态方法
public static void show(){
System.out.println("静态方法...");
new Ch03().fun();
}
public static void main(String[] args) {
System.out.println(Ch03.name);
//直接调用静态方法
Ch03.show();
Ch03 ch03 = new Ch03();
System.out.println(ch03.name);
//通过对象调用静态方法
ch03.show();
}
}
注意:
静态方法无论在哪里都是类名.方法名调用,同一个类的静态方法之间可以省略类名。
用对象.方法或对象.属性是可以调用的,但严格来说,用对象来调用静态的方法、属性是错误的,尽量不要这么调用,建议直接 类名.静态属性(方法)
静态方法没有重写的概念
代码块(不是方法):(理解)
代码块又称为初始化块,属于类的一个成员,它是将逻辑语句封装在方法体中。
通过{}包裹。代码块没有方法名,没有参数,没有返回值,只有方法体。
他是不需要通过对象或类进行显示的调用,他会在类加载或者创建对象时主动的《隐式》调用。
可用于给静态常量初始化,创建静态常量不初始化,在代码块中初始化是可以的
1、静态代码块
一个类被加载时会被调用一次,做一些初始化的工作(只走一次)
可以写多个静态块,但一般只写一个
2、实例代码块
每次创建实例(创建对象)时,会被调用一次,用的较少(每次创建对象都走)
可以写多个,但一般只写一个
举例说明
public class Ch01 {
static final String STR;
static {
// 静态代码块
System.out.println("静态代码块...");
STR = "10";
}
{
// 实例代码块
System.out.println("实例代码块...");
}
public static void main(String[] args) {
Ch01 ch01 = new Ch01();
Ch01 ch02 = new Ch01();
/*会输出: 静态代码块
实例代码块
实例代码块
*/
//因为静态代码块只在类被加载时被调用一次(无论再怎么创建对象都只走一次)
//实例代码块会随着对象的一次创建而被调用一次
}
}
面试题
//父类
public class Father {
public Father() {
System.out.println("父类的构造器...");
}
{
System.out.println("父类的实例块...");
}
static {
System.out.println("父类的静态块...");
}
public static void main(String[] args) {
Father father = new Father();
}
}
//子类
public class Ch02 extends Father {
public Ch02() {
System.out.println("子类的构造器...");
}
{
System.out.println("子类的实例块...");
}
static {
System.out.println("子类的静态块...");
}
public static void main(String[] args) {
new Ch02();
}
}
问:输出的顺序是?
当没有继承关系,就一个类时,静态块-->实例块-->构造器
当有继承关系时,父类的静态块-->子类的静态块-->父类的实例块-->父类的构造器-->子类的实例块-->子类的构造器
父类优于子类,静态优于非静态
内部类:(理解)
在一个类内部进行其他类结构的嵌套操作。
-
实例内部类
实例内部类中除了静态常量之外,其他的静态不能存在
-
静态内部类
举例说明:
public class Ch01 {
// 实例内部类
// 不能有静态
public class Inner {
public static int x;
{
System.out.println("实例内部类被加载...");
}
public void show(){
}
public Inner(){
}
class Innerinner{
}
private String name;
}
// 静态内部类
public static class InnerStatic {
static {
System.out.println("静态内部类被加载...");
}
public void show(){
}
public static void main(String[] args) {
}
}
public static void main(String[] args) {
// 这就是实例内部类的对象
Inner inner = new Ch01().new Inner();
// 静态内部类的对象
InnerStatic innerStatic = new Ch01.InnerStatic();
}
}
外部类(理解)
若外部类想用public声明,则类名必须和.java的文件名相同。
外部类就是两个类,生成的.class文件是两个独立的.class。
开发中,尽量不要写外部类。
举例说明:
public class Ch05 {
int i = 10;
public static void main(String[] args) {
}
}
//外部类
class Outer {
public static void main(String[] args) {
}
}
设计模式
设计模式是人们为软件开发中抽象出可重复利用的解决方案。
软件开发工程师之间沟通的“行话”。
面向对象的设计原则(了解)
-
开闭原则(Open Close Principle)
对扩展开放,对修改关闭。(继承,实现接口) 我们可以通过“抽象约束,封装变化”来实现开闭原则。
通过接口或者抽象类为软件定义一个相对稳定的抽象层。
将相同的可变因素封装在相同的具体实现类中。派生一个实体类就可以了。
-
里氏代换原则
子类继承父类时,除了添加新的方法完成新增的功能外,尽量不要重写父类的方法
-
依赖倒转原则
要面向接口编程,不要面向实现编程。
a. 每个类尽量提供接口或抽象类,或者两者兼备
b. 变量的类型声明尽量是接口或者是抽象类
c. 任何类都不应该从具体类派生
d. 使用继承时,要遵循里氏代换原则。
-
接口隔离原则
使用多个隔离的接口。 -
迪米特法则
-
合成复用原则
-
单一原则:一个类只做一件事
单例模式(理解)
一个类只有一个实例。
思路:
- 别人不能new,构造器私有化,不能在类的外部通过new去实例化。
- 在该类内部产生一个唯一的实例对象,把它封装成static类型。
- 定义一个静态方法返回这个唯一的对象。
饿汉式单例模式
不管以后会不会使用到该实例化对象,先创建了再说,很着急的样子。
实现的办法就是直接new实例化。
public class Ch03 {
private static final Ch03 ch03 = new Ch03();
private Ch03(){}
public static Ch03 getInstance(){
return ch03;
}
}
懒汉式(延迟加载)
什么时候调用getInstance方法,什么时候new
这种懒汉式在多线程环境中完全错误的,根本不能保证单例的状态,可能会出现线程问题。
需要《加锁》
举例说明
public class Ch04 {
// 将自身实例化对象设置为一个属性,现在是没有赋值的
private static Ch04 ch04;
// 构造器私有化
private Ch04(){
}
public static Ch04 getInstance() {
if(ch04 == null){
ch04 = new Ch04();
}
return ch04;
}
}
内部类实现单例
也是懒汉式的一种,这种懒汉式没有线程的问题。
结合了饿汉式和懒汉式的优点:
只要不调用getInstance方法,就不会使用内部类
内部类一旦被使用一次只会被初始化一次,以后一直用的时INSTANCE静态常量了。
public class Ch05 {
// 私有化构造器
private Ch05(){
}
public static Ch05 getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder {
private static final Ch05 INSTANCE = new Ch05();
}
}
箭头函数:JDK8的新特性(理解)
函数式接口:如果一个接口只有一个抽象方法,这个接口就称为函数式接口。可以用注解@FunctionalInterface标识。
- 有参数,有返回值。
(i,j) -> {
return i + j;
}
如果方法体只是一句返回值(i,j) -> i+j - 有参数,无返回值
(i,j) -> {
// 方法体
}
如果方法体只有一句话(i,j) -> 方法体的一句话 - 无参数
()->{
方法体
}
//接口
@FunctionalInterface
public interface Inter01 {
//抽象方法
String show();
//默认方法
default void fun(){
}
}
//类
public class Ch06 {
public static void test(Inter01 inter01) {
// System.out.println(inter01.show());
inter01.show();
}
public static void main(String[] args) {
//老方法,使用匿名实现类来完成重写
test(new Inter01() {
@Override
public String show(int i,int j) {
return i + "," + j + "匿名实现类重写的show方法...";
}
});
//箭头函数
/*
这个结构可以分为三部分
第一部分,小括号包裹形参,类型不要
第二部分,->
第三部分,->方法体
当重写的方法体只有一句话时,可以精简到这种
() ->System.out.println("重写的show方法...")
当重写的方法只是有一句返回值时,可以精简到这种
() -> "你好"
*/
//test((1,2) -> {方法体});
test(() -> "你好");
}
}
标签:20220727,笔记,class,静态,实例,static,大禹,new,public 来源: https://www.cnblogs.com/ldydj/p/16526742.html