东软实训 JavaSE day02

JVM内存模型

东软实训 JavaSE day02

  • 堆是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,几乎所有对象都被分配到了堆内存中

  • 方法区

    方法区主要是用来存放已被虚拟机加载的类相关信息,包括类信息、常量池等信息

  • 程序计数器

    是一块很小的内存空间,主要用来记录各个线程执行的字节码的地址,例如分支、循环、跳转、异常、线程恢复等都依赖于计数器。

  • 虚拟机栈[方法栈]

    当创建一个线程时,开辟一个虚拟机栈空间,用来保存方法的局部变量和返回地址等信息

    每一个方法的调用都伴随着栈帧的入栈操作,方法的返回则是栈帧的出栈操作。

  • 本地方法栈 native

    本地方法栈跟虚拟机栈的功能类似,虚拟机栈用于管理 Java 方法的调用,而本地方法栈则用于管理本地方法的调用。

    但本地方法并不是用 Java 实现的,而是由 C 语言实现的。

模拟栈溢出

public class Test{

    public static void main(String [] args){
        say("hello");
    }
    
    public static void say(String content){
        System.out.println(content);
        say(content);
    }
}

模拟堆溢出

public class Test{
    int [][][] data = new int [10000][10000][10000]; //自行调整大小
    public static void main(String [] args){
        //创建一个占用空间很大的对象
        new Test();
    }
}

Static修饰符

含义

用来修饰方法、成员变量(常量),代表这些属于类级别的,可以直接通过类名.来调用【推荐】。也可以通过对象.来调用

类成员

含义

用static修饰成员变量(常量),代表这些属于类级别的。

特点

  • 随着类加载而初始化,全局只有一份,所有对象共享

  • 类名.成员变量(常量)来调用

类方法

含义

static 修饰的方法

特点

  • 属于类级别的,类名.方法名([参数类表])方式来调用
  • static方法只能访问static方法或static成员变量(常量)
  • 非static方法可以访问static方法或static成员变量(常量)

使用场景

  • 一般作为工具类(自行查看Arrays的方法)

成员变量细分

static

非static

成员方法细分

static

非static

变量分类&生命周期

变量种类 存放位置 生命周期开始 生命周期结束
局部变量 方法里面的 方法调用开始 方法调用结束
类成员变量(static) 和方法级别 类的加载开始 类的卸载结束
对象成员变量(非static) 和方法级别 对象的创建 对象被回收

Package

含义

是类的容器,在磁盘中以文件夹的方式存在

作用

  • 归类,将同类功能的类放入相同的包
  • 避免名字相同的类名冲突

语法规范

  • 公司域名倒写,遇到数字前面添加_
  • 全部小写

常见的包名

  • java.lang [此处会自动导入包]
  • java.text 比如SimpleDateFormat
  • java.util 比如List
  • java.net

Import

含义

import就是在java文件开头的地方,先说明会用到那些类。在代码中只用类名指定某个类。

语法

  • import 包名.子包N.类名; //导入指定包下的指定类

  • import 包名.子包N.*; //导入子包下的所有类

案例

import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class ImportTest {
	public static void main(String[] args) {
		
		//会自动导入java.lang下的类
		String name ="test";
		
		SimpleDateFormat simpleDateFormat = null;
		
		DateFormat dateFormat=null;
	}
}

封装

含义

将抽象的成员特征和行为放到类中,隐藏内部细节,并对外提供需要访问的接口

为什么封装

TODO

如何隐藏

使用范围修饰符

范围修饰符

含义

控制访问的权限【或可见性】

有哪些

种类 同类 同包 子类不同包 其他
public y y y y
protected y y y n
默认 y y n n
private y n n n

使用优先级

private>protected>默认>public

entity

  • 私有的字段,根据情况对外setter或getter方法
  • 对于boolean型不建议使用is开头的字段

this

含义

当前对象本身

使用场景

  • 调用构造器
  • 避免参数二义性
  • 方法链

注意点

静态方法中不能使用this关键字

继承

含义

在原有的代码结构上扩充新的功能,继承解决的是代码的重复的现象

语法

修饰符 class 类名 extends 父类类名{

​ //扩展新的功能

}

案例

public class Bird {
	private String name;
	
	String sex;
	
	public Bird(){
		
	}
	public Bird(String name){
		this.name = name;
	}
	
	public void eat(){
		System.out.println("吃东西");
	}
}
//企鹅
public class Pengui extends Bird {

}
public class Ostrich extends Bird {
	
	public static void main(String[] args) {
		
		Ostrich ostrich = new Ostrich();

        System.out.println(ostrich.sex);
		ostrich.eat();
		
		//Ostrich otherOstrich = new Ostrich("xx");
	}
}

注意点

  • 类是不能多继承的
  • 父类私有方法、字段是不能继承
  • public protected修饰的方法、字段可以被继承
  • 默认修饰的方法、字段如果不能同一个包则不能继承
  • 构造器不能被继承

final修饰符

含义

代表最终

修饰什么

  • 字段
    • final int age =1; //代表age就是常量
  • 类名
    • 代表该类不能被其他类继承
  • 方法
    • 代表该方法不能被重写【TODO】

案例

public class FinalDemo {
	//成员常量
	final int age=1;
	
	//修饰类
	   //最终的意思,不能被其他类继承 自行尝试
	
	//修饰方法
	   //代表该方法不能被重写【TODO】
	
	public void say(){
        //局部常量
		final int age=1;
	}
}

子类实例化过程

过程

在创建子对象会先调用父类的构造器创建父对象

注意点

父类的构造器不能全部都是私有的,根据情况需要指定调用父类的构造器。

案例

public class Animal {
	
	String name;
	
	private Animal(){
		System.out.println("父被对象被创建了");
	}
	
	public Animal(String name){
		this.name = name;
	}
}
public class Cat extends Animal{
	
	//子类实例化过程
	   //在子类的构造器第一行会调用父类的构造器创建父对象
  
	public Cat(){
		//隐藏super();
		
		//指定父类可以访问的构造器
		super("小花猫");
		System.out.println("子对象被创建了");
	}
	
	public static void main(String[] args) {
		Cat cat = new Cat();
	}
}

方法覆盖(重写\覆写)

含义

子类继承了父类的行为,但是有些行为不满足现有要求。

格式

@Override
范围修饰符 返回类型 方法名(){
    扩展的需求
}

案例

public class Bird {
	
	private String name;
	
	
	protected void move(){
		System.out.println("翅膀...");
	}
	
	public static void destroy(){
		
	}
}
public class Pengui extends Bird {

	@Deprecated
	private int age;
	
	//此时父类的move不满足要求,可以通过重写
	
	//语法
	   //编写和父类一样的方法,然后在方法体加以扩展。
	
	//注意点
	   //范围修饰符只能>=父类方法的。
	   //不能抛出比原来更大的异常
	   //final修饰的方法不能被重写
	   //static修饰的方法不能被重写
	
	@Override   //注解 1.5
	protected void move(){
		 System.out.println("脚。。");
	}
	 
	
	//注解
	   //含义
	      //用来修饰方法、字段、类名、参数名
	   //常见
	      //@Override 方法重写
	      //@Deprecated 代表过时,不建议
	public static void main(String[] args) {
		Pengui pengui = new Pengui();
	}     
}

约束

  • 范围修饰符只能>=父类方法的。
  • 不能抛出比原来更大的异常
  • final修饰的方法不能被重写
  • static修饰的方法不能被重写

注解

含义

用来修饰方法、字段、类名、参数名

常见

  • @Override 方法重写
  • @Deprecated 代表过时,不建议

Super(父对象)

含义

父对象

场景

  • 子类的构造器显示调用父类的构造器
  • 调用父类的方法
  • 调用父类的字段【成员变量、成员常量】

案列

public class Animal {
	
	int age;
	
	public Animal(int age){
		this.age = age;
	}
	
	public void move(){
		System.out.println("脚。。。");
	}
}
public class Fish extends Animal{
	int age;
	public Fish(){
		super(10);
	}
	@Override
	public void move() {
		super.move();
	}
	
	public void sayInfo(){
		System.out.println("年龄"+super.age);
	}
	
	//super
	   //调用父类构造器
	   //调用父类方法
	   //调用父类字段
	public static void main(String[] args) {
		
		Fish fish = new Fish();
		//fish.move();
		
		fish.sayInfo();
	}
}

Object

含义

除了Object之外一切类的超类。

常用方法

  • toString
  • equals
  • getClass
  • finilize
  • hasCode

案例

public class ObjectTest {
	private String name;
	
	//Object
	   //含义:除了Object之外一切类的超类
	   //常用的方法
	      //toString
	      //getClass
	      //equals   判断两个对象的地址是否一样,里面使用==,一般根据情况重写该方法
	      //finilize 当某个对象被GC回收的时候会触发该方法,实际不要去重写
	      //hasCode  
	
	public static void main(String[] args) {
		
		ObjectTest objectTest = new ObjectTest();
		
		System.out.println(objectTest);
		System.out.println(objectTest.toString());
		
		//某个类只会加载一次
		//User.java --- > User.class --类加载器-->JVM(方法区)
		                                         //如何获取User类相关信息
		                                            //方式一:对象.getClass();
		                                            //其他方式后面回顾
		//clazz包含ObjectTest这个类的信息
		Class clazz = objectTest.getClass();
		
		//获取包名
		System.out.println(clazz.getPackage().getName());
		
		//ObjectTest 类的简单名称
		//com.neu._09object.ObjectTest 类名
		 
		System.out.println(clazz.getSimpleName());
		
		System.out.println(clazz.getName());
		
		ObjectTest one = new ObjectTest();
		ObjectTest two = new ObjectTest();
		
		System.out.println(one.equals(two));
	}
}

引用数据类型转换

子类型对象可以自动赋值给父类型对象

父类型对象赋值给子类型对象需要强制转换,如果类型不一样会出现ClassCastException异常

案例

public class Animal {
}
public class Cat extends Animal{
}
public class Fish extends Animal{
}
public class User {
	
	public static void main(String[] args) {
		
		//ClassCastException
		
		Animal cat = new Fish();
		
        //instanceof 用来比较某个对象是否是某类的实例
		if(cat instanceof Fish){
			Fish fish = (Fish) cat;
			System.out.println(fish);
		}else if(cat instanceof Cat){
			Cat otherCat = (Cat) cat;
			System.out.println(otherCat);
		}
	}
}

多态

含义

同一个对象有多种状态,只有运行的时候才能确定

原理

  • 继承
  • 实现接口 TODO

案例

public class Animal {
	String name;
	public Animal(String name){
		this.name = name;
	}
	
	public void print(){
	   System.out.println(this.name);	
	}
}
public class Cat extends Animal{
	public Cat(String name) {
		super(name);
	}
}
public class Fish extends Animal{

	public Fish(String name) {
		super(name);
	}
}
public class Test {
	//多态
	   //含义:同一个对象有多种状态,只有运行的时候才能确定。
	   //原理
	       //继承
	       //实现接口 TODO
	public static void main(String[] args) {
		
		Test test = new Test();
		
		Cat cat = new Cat("猫");
		test.like(cat);
		
		Fish fish = new Fish("小鱼");
		test.like(fish);
	}
	
	public void like(Animal animal){
		System.out.println(animal);
	}
	
	//没有使用多态
	/*
	public void like(Cat cat){
		System.out.println(cat);
	}
	
	public void like(Fish fish){
		System.out.println(fish);
	}
	*/
}

代码块

含义

种类

  • 静态代码块
  • 普通代码块

final

修饰字段=>常量

修饰方法=>该方法不能被重写

修饰类=>该类不能被继承

单例设计模式

含义

某一个类最多只能创建一个实例。

好处

避免重复创建对象

如何实现

  • 饿汉式
  • 懒汉式

饿汉式

步骤

  • 私有的构造器
  • 提供static final 修饰的该类型的常量,且赋值为当前单例对象
  • 对外提供public static用于获取单例对象

案例

public class ATM {
	//只会创建一次
	private final static ATM atm = new ATM();

	private ATM(){
	}
	
	public static ATM getInstance(){
		return atm;
	}
	
	public void output(int money){
		System.out.println("取钱"+money);
	}
}
public class User {
	
	public static void main(String[] args) {
		
		ATM atm = ATM.getInstance();
		atm.output(2);
		 
		ATM other = ATM.getInstance();
		//结果为true
		System.out.println(atm == other);
	}
	
	//ATM 单例
	
	//第一步:避免重复创建对象,private 构造器
	//第二步:编写static的变量且初始化
	//第三步:提供用于获取实例的方法给外部调用

}

抽象类

含义

abstract 修饰的类

为什么

TODO

案例

自行编写

注意点

  • 抽象类中可以没有有抽象方法,可以有普通方法
  • 抽象方法一定要在抽象类中
  • 抽象方法不能否final修饰的
  • 抽象方法不能static的
  • 抽象类的构造器不能全部都是私有的
  • 抽象类不能是final修饰的
  • 抽象类不能直接new

作业

  • 自行模拟一个ClassCastException异常-

  • 自行编写一个单例

  • 自行编写一个抽象类的使用场景

  • 思考static 能否修饰局部变量?

  • 思考多态的含义、实现原理

  • 思考final的使用场景

  • 思考四大作用范围的作用域

上一篇:Note_Logistics_Day02


下一篇:学习Java.Day02