Java基础视频教程笔记

  • 简介
  • 正文
  • ==JVM Java Virtual Machine==
  • 栈区 Stack Segment
  • 堆区 Heap Segment
  • 静态区 Data Segment
  • 代码区 Code Segment
  • ==数组==
  • 声明
  • 分配空间
  • 赋值
  • 处理数据
  • 初始值
  • 数组长度
  • sort()
  • 数组算法
  • 数组复制
  • 数组查找
  • 插入算法
  • 冒泡排序
  • 多维数组
  • for-each遍历二维数组
  • ==程序执行过程==
  • 基本分区
  • 储存new出来的对象 Heap Segment
  • 储存局部变量 Stack Segment
  • 储存静态变量和字符串常量 Data Segment
  • 储存代码 Code Segment
  • ==类与对象==
  • 对象的初始化过程
  • 继承
  • 属性继承
  • 方法继承
  • 重载(@overload)&重写(@override)
  • 构造方法继承
  • 对象的转型
  • 对象的向上转型
  • 对象的向下转型
  • instanceof 关键字
  • 多态
  • Object类
  • toString()方法
  • equals()方法
  • 抽象类(未完成)
  • ==构造方法相关==
  • 构造代码块
  • 构造方法相互调用
  • ==static关键字==
  • ==main()方法(主方法)==
  • ==Class path 环境变量==
  • ==Java文档注释==
  • ==静态代码块==
  • ==设计模式 - Java==
  • 单例设计模式
  • ==final关键字&常量==
  • 附录
  • Eclipse操作
  • 配套练习实例


简介

Java基础视频教程 **2012版** 学习前有一定Java基础 本篇作为自我记录

在学习了阿里云大学的内容后觉得本篇的内容有很多不够详细且较为零散,
更为详细的记录内容见以下链接
文章链接还未进行整理

正文

JVM Java Virtual Machine

JVM分为四个区域,分别为栈区,堆区,静态区,代码区

栈区 Stack Segment

存放函数的参数值,局部变量的值等,超过这个变量的作用域时
会被系统GC自动释放存在于JVM内存中的资源
优点 存取速度较块
缺点 在栈区的数据大小和生存区必须是确定的,没有灵活性

堆区 Heap Segment

存放new创建的对象和数组,JVM不定时查看这个对象,
如果没有引用指向这个对象就会被回收
优点 可以动态分配JVM内存
缺点 要在运行时分配JVM内存 速度慢

静态区 Data Segment

代码区 Code Segment

数组

声明

int[] a;  //或者int a[];

分配空间

a=new int[5];

可以统一写成

int[] a=new int[5];

赋值

a[0]=1;

可以统一写成

int[] a={1,2,3};

或者

int[] a=new int[]{1,2,3}

可使用for进行循环键盘获取赋值

处理数据

初始值

int[]初始为0 String[]初始为null

数组长度

基本数据类型为.length 对象数组为.length()

sort()
import java.util.Arrays;
Arrays.sort(a);

默认升序排列
降序打印可以从length-1打印到0

数组算法
数组复制

for( ; ; )依次赋值即可

数组查找

for( ; ; )依次查找即可

插入算法

先将数据插入到最后一位,然后从后往前依次比较大小排序

冒泡排序

从a[0]开始依次冒泡,前位比后位大时交换位置,使得最大的数据拍到最后一位,
下一次遍历个数-1,总遍历次数为length-2,即i<length-1

多维数组

只有最高层的引用跨区 二维及以上的都在堆区进行引用

int a[][]={{ },{ },{ }};

初始化从高维往低维存放

int a[][]=new int[3][];
a[1]=new int[2];
for-each遍历二维数组
for(int[] b:a)
{
	for(int c:b)
	{
		System.out.print(c+" ");
	}
	System.out.println();
}

程序执行过程

程序源代码储存在硬盘中,双击后将源码Load到内存区
内存区的代码由系统分析,找到main()方法后开始执行

基本分区

执行过程中进行内存管理,不同操作系统的内存分区可能不同
但基本的分区可分为

储存new出来的对象 Heap Segment
储存局部变量 Stack Segment
储存静态变量和字符串常量 Data Segment
储存代码 Code Segment

类与对象

类 即模具 规定创建的对象的属性和方法
类名称首字母大写 public class Human{}
一个文件允许存在多个类,但只允许存在一个公有类
对象的作用:对象是用来封装数据的,只要这个类里面有非静态的成员时,那这个类的使用时,对应对象就必须存在

对象的初始化过程

1、检索到需要创建对象时,根据类名(new 类名())查询对应类在硬盘上进行加载进入内存
2、如果有static静态代码块,执行静态代码块,同时静态成员和普通方法也会随着类的加载而加载
3、在堆中开辟空间,分配内存地址
4、在堆中建立对象特有属性,并同时对特有属性进行默认初始化
5、对属性进行显式初始化
6、若存在构造代码块,执行构造代码块,对所有对象进行初始化
7、执行对应的构造函数,对对象进行初始化
8、将内存地址传递给栈中的类名类型变量

继承

利用extends关键字实现类之间的继承联系,提高代码复用性并简化代码
注意:不要为了获取其他类的功能而产生继承关系,即不要为了继承而继承
父类中private修饰的成员对象/方法会被继承到子类,但无法被访问
Java实现的是多层继承而非多继承,在多层继承中最下层的子类拥有整个继承体系
最上层的父类定义了所有子类的共性描述
多继承存在问题,若使用多继承,若多个父类定义了相同名方法,子类对象不确定运行哪一个
Java不支持多继承,但保留了该机制,通过接口的方式实现

属性继承

子类定义了与父类同类型同名的属性后会把父类的属性覆盖,但可以在该子类中使用 super.属性名称 访问父类的属性
若子类中使用this.属性名称进行访问,此时若不存在该属性且父类中存在同名属性,则会访问父类中的该属性,实际上实现的是super的效果,而super则直接跳过在本类中查找,直接到父类中查找所需变量

方法继承

当子类中出现和父类相同的方法时,子类对象调用该函数运行的是本类中的方法,该特性就是方法的特性之一,称为重写/覆盖(@override)
重写的时候要保证子类的对应方法的权限要大于父类方法的权限,否则将编译出错
public > (default) > private //protect视频中没提到
静态的方法只能覆盖静态的

重载(@overload)&重写(@override)

重载只看同名的方法的参数列表,重写则要求子类父类方法完全一样,内容不同

构造方法继承

构造方法不能够被重写
在对子类对象进行初始化的时候,父类的构造方法同样也会运行,因为子类的构造函数默认第一行存在一条隐式的语句 super();

对象的转型

对象的向上转型

子类转成父类 默认进行 父类引用指向子类对象

class Animal{
	void sleep(){}
}
class Cat extends Animal{
	void catSleep(){}
}
class Dog extends Animal{
	void dogSleep(){}
}
public class Test{
	public static void main(){
		Animal a=new Dog();//向上转型
	}
}

向上转型产生的对象只能访问到父类所具有的属性和方法,若需要访问到子类的属性和方法需要使用强制转换,例如:

(Dog)a.dogSleep()
对象的向下转型

父类转成子类 强制进行

public class Test{
	public static void main(){
		Animal a=new Dog();//向上转型
		Dog d=(Dog)a;//向下转型
	}
}

若此时增加

Cat c=(Cat) d;

编译的过程中不会提示有问题,但运行时会出现提示 java.lang.ClassCastException 表示类型不匹配,此时可以使用instanceof关键字进行对象匹配

instanceof 关键字

用于测试左边的对象是否是右边的实例,若满足返回true,否则返回false
测试的左右两边要存在继承关系,否则会报错

System.out.println(d instanceof Dog); //结果为true
System.out.println(d instanceof Animal); //结果为false
System.out.println(d instanceof Cat); //报错

多态

可以理解成事物存在的多种形态,例如动物存在猫、狗、猪、牛
多态的体现为父类引用指向子类对象,前提是类与类之间存在关系,可以是继承关系,也可以是实现关系(接口),且必须有重写
多态的优点在于大大提升了程序的可扩展性
多态的缺点在于只能用父类的引用访问到父类中的成员,无法访问到子类的成员,即父类中若不存在对应方法但子类存在时会在编译期间报错
多态成员变量特点:
1、编译期间:参阅的是引用型变量所属的类中是否有调用的方法
2、运行期间:参阅对象所属的类中是否有调用的方法

class Animal(){
	void sing(){}
}
class Cat extends Animal(){
	void sing(){
		System.out.println("Meo");
	}
}
class Dog extends Animal(){
	void sing(){
		System.out.println("Wuuu");
	}
}
public class Test{
	public static void main(){
		public void fun(Animal a){
			a.sing();
		}
		Cat c=new Cat();
		Dog d=new Dog();
		fun(c);
		fun(d);
	}	
}
/*
	运行结果为
	Meo
	Wuuu
*/

Object类

Object是一个特殊的类,是Java中所有对象的直接的或者间接的父类/根父类/基类,里面所定义的功能应当是所有的对象所具备的
定义新类的时候并没有指明要继承某类,但它默认继承Object类

toString()方法

toString()方法为Object类中所包含的方法 返回值为该对象的地址值

Cat c=new Cat();
System.out.println(c);
//结果为c.toString()的返回值即该对象的地址值
equals()方法
class Cat
{
	String name;
}
public class test
{
	public static void main(String args[]){
		Cat c=new Cat();
		Cat c2=new Cat();
		c.name="abc";
		c2.name="abc";
		System.out.println(c.name.equals(c2.name));
		System.out.println(c.name==c2.name);
		//字符串池的存在导致==的结果是true
		String s1="abc";
		String s2="abc";//均指向同一字符串池中字符串
		System.out.println(s1==s2);
		System.out.println(s1.equals(s2));
		System.out.println(s1);
		//直接赋值的结果与对象操作相同
		String s3=new String("abc");
		String s4=new String("abc");
		System.out.println(s3==s4);//false
		System.out.println(s3.equals(s4));//true
		//equals比较的是内容,==比较的是内存地址
		System.out.println(s1==c.name);
		System.out.println(s1.equals(c.name));
		System.out.println(s1==s3);//false
		//进行另外申请的new String()的不在该字符串池中,可用intern()手动入池
	}
}

抽象类(未完成)

构造方法相关

构造代码块

在创建类的时候运行的部分,举例如下

public class A(){
	public static void main(String args[]){
		Student A=new Student();
	}
}
class Student(){
	String name;
	Student(){
		System.out.println("无参构造执行");
	}
	Student(String name){
		this.name=name;
		System.out.println("有参构造执行");
	}
	{
	System.out.println("构造块执行");
	}
}
/*
	执行结果为:
	构造块执行
	无参构造执行
*/

构造方法相互调用

//方法1
class Student(){
	String name;
	int age;
	Student(String name){
		this.name=name;
	}
	Student(String name,int age){
		this(name);
		this.age=age;
	}
}
//方法2
class Student(){
	String name;
	int age;
	Student(String name){
		this(name,0);
	}
	Student(String name,int age){
		this.name=name;
		this.age=age;
	}
}

this.name=name;//用于区分局部变量和成员变量同名的情况
this.方法名;//代表本对象内的某方法
this();//代表本类中对于满足参数表的方法的引用,构造函数之间调用只能通过this()完成
this();super();二者不能同时存在,因为二者均必须出现在构造函数第一行

static关键字

在面向对象过程中,如果某对象的的某个成员属性是共通的,此时若作为成员属性存储,则会在堆内存中
造成大量的内存浪费,此时可以使用static关键字修饰,将数据存放在静态区(别称包括数据区,方法区,
共享区等等)中,该静态成员变量(别称类变量)被所有该类型对象共享
static:是一个修饰符,用作修饰成员(成员变量,成员方法),被修饰后的成员唯一存在,
当成员被static修饰后,该变量多了一种访问方式,可以使用类名直接访问(类名.静态变量名)
特点:被修饰后静态成员变量会随着类的加载而加载,且优先于对象存在Data Segement中,
而实例变量则是随着对象的建立而被创建,存在于堆内存区中
静态成员变量无法直接使用非静态方法修改
静态方法只能访问静态成员,非静态方法既能访问静态成员,也能访问非静态成员
静态方法不能定义this super关键字,因为静态方法优先于对象存在
若静态工具类不希望能够被生成对象,则该类的无参构造方法可以人为设置为private

main()方法(主方法)

public static void main(String args[]){
	//System.out.println("Hello World");
}

1、public 访问修饰符,代表该类/该函数的访问权限最大
2、static 代表主函数随着类的加载而加载
3、void 主函数没有返回值
4、main 主方法名称,并不是关键字,但这个单词能被JVM识别
5、String[] args/String args[] 两种写法均可,代表JVM在调用主函数的时候
传入了一个String[]类型的参数 可以在命令行下通过 java 类名 字符串(数组) 的方式传入参数,
传入字符串数组时用空格分隔

Class path 环境变量

Path主要功能是设置JDK的可执行命令,classpath 主要是在执行的时候作用,告诉JVM类的保存路径
命令行方式设置:
set classpath=“路径”
set classpath=. //设置为在当前目录下查找文件
set classpath=.;E:\java //分号隔开多个路径,依次在各个路径下寻找文件
命令行方式设置路径仅对该命令行窗口有效,关闭后classpath将恢复原本设置
修改默认设置方法(Win10):资源管理器-(右击)此电脑-属性-高级系统设置-环境变量

Java文档注释

/**
(以下为对public static int max(int[] arr)的描述)
取int数组里面的最大值
(使用文档标识符对方法进行注释)
@param arr 传入一个int数组
@return 返回一个int数值
@auther 作者名称
@version 版本名称
*/

编写完成后使用javadoc.exe进行提取
javadoc -d Mydoc -author -version Array.java
要进行提取的类要保证类是public的
提取后的文件是以网页的形式存在的 进入文件夹双击index.html
若是方法/构造方法声明为private 则该部分不会被javadoc.exe 转换

静态代码块

static{
	//静态代码块中执行语句
}

静态代码块随着类的加载而执行,并且只会执行一次,优先于主函数,用于对类进行初始化

设计模式 - Java

设计模式即针对某类问题最有效的解决方法,Java中共被总结出23种设计模式,这些模式不应记忆代码,而是作为思想进行理解运用

单例设计模式

用于解决一个类只在内存中允许存在唯一一个对象的需求,思路如下:
1、禁止其他应用程序通过此类来创建对象
2、既然外部无法通过此类创建对象,则若要使用该对象应当在本类中创建该对象
3、为了其他应用程序能够访问到该对象,应当对外界提供该对象的访问方式
转换为代码表达如下:

class Person(){
	private Person();						//1、私有化构造方法
	static Person p=new Person();			//2、在本类中创建本类对象
	public static Person getInstance(){		//3、对外界提供访问方法
		return p;
	}
	//由于第三步执行的时候该对象的构造已经被禁止了,
	//此时要对外界提供访问方法,就需要将其声明为static
	//而静态方法无法访问非静态成员,因此p也需要声明为静态成员
}

//使用方法
Person a=Person.getInsetance();
Person b=Person.getInsetance();
//此时若对a执行person的成员属性修改,b的成员属性同样会被修改,因为二者共用同一个对象

final关键字&常量

final可以修饰类、函数、变量(成员变量,局部变量)
被final修饰后的类无法被其他类继承 被final修饰后的函数不可以被重写 被final修饰后的变量不允许被再次赋值(即c++中const关键字的作用)因此该变量需要在声明时进行赋值 该变量称为常量
常量有自己的命名规范 字母全部要求大写 如果名字由多个单词组成,由下划线(_)隔开
public final static 共同修饰的变量被称为全局常量,此时该常量被移入数据区

附录

Eclipse操作

alt+shift+a 多行共同编辑模式on/off
alt+shift+s 打开源码菜单 可选择自动生成getter setter和构造方法

配套练习实例

猜拳游戏(涉及取随机数)
日历制作(解决实际问题,格式化输出)
学生管理系统(类与对象的综合应用)
静态工具类(static关键字的使用,常用工具类的制作)