java基础的系统学习

基础知识

数据类型

基本数据类型:int short long double boolen float char byte
引用数据类型:String (所有的类class都是引用数据类型)

变量

局部变量:方法里的
成员变量:类里的,系统会默认赋值 boolen:false char:\u0000
引用数据类型:null
成员变量有2种:
一种是被static关键字修饰的变量,叫类变量或者静态变量;
另一种没有static修饰,为实例变量。

class One
{ 
float x; //x为实例变量
static int y; //只要有关键字static, y为类变量
}

实例变量:对象级别的变量,实例变量是指在类的声明中,属性是用变量来表示的
变量赋值的原则:将盒子中保存的“值”复制一份传过去,值可能是数字也可能是对象的内存地址

类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。

而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。

变量和作用域

  1. 类的静态变量在内存中只有一个。静态变量位于方法区,被类的所有实例共享。静态变量的生命周期取决于类的生命周期(即类何时被加载和卸载)。

  2. 类的每个实例都有相应的实例变量。实例变量位于堆区中。实例变量的生命周期取决于实例的生命周期(即实例何时被创建及销毁)。

  3. 假如成员变量(包括静态变量和实例变量)是引用变量,那么当该成员变量结束生命周期时,并不意味着它所引用的对象也一定结束生命周期。变量的生命周期
    和对象的生命周期是两个不同的概念。

  4. 局部变量位于栈区,其生命周期取决于所属的方法何时被调用及结束调用。

    总结一下:
    局部变量位于栈区,静态变量位于方法区,实例变量位于堆区,方法的字节码位于方法区,对象本身位于堆区,对象的引用位于栈区。
    ————————————————
    原文链接:https://blog.csdn.net/woainike/article/details/6413984

标识符:
区分大小写,不能以数字开头
用来命名常量、变量、类和类的对象等

关键字
Java 语言目前定义了 51 个关键字,这些关键字不能作为变量名、类名和方法名来使用。以下对这些关键字进行了分类。

  1. 数据类型:boolean、int、long、short、byte、float、double、char、class、interface。
  2. 流程控制:if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally。
  3. 修饰符:public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native。
  4. 动作:package、import、throw、throws、extends、implements、this、supper、instanceof、new。
  5. 保留字:true、false、null、goto、const。

字符编码: 转换作用
ASCII码:一个字符编码
java的源码用的是unicode编码,所以标识符可以写中文

一张表描述的文字与二进制之间的关系。 编码解码时采用同一套字典/对照表,则不会出现乱码

转义字符:

\t tab
\n 换行
\表示一个
’ 表示一个’
" "
\u 字符的unicode编码

强制类型转换:

小容量–>大容量:自动转换
大容量–>小容量:(类型)

键盘输入:

Scanner s = new Scanner(System.in);

class

1、.java文件中可以定义多个类
2、public类不是必须的,但public类应该在名为B.Java的文件中声明,类名与文件名一致
3、一个class会生成一个.class文件
4、每个类中都可以有一个入口main,想从哪个入口就加载哪个类【但是不会用】

源码阅读

native + 以分号结束的方法,表示调用了c++的.dll文件。
system.out.println(引用) 会自动输出pro.toString() -->name@hash(addr)

方法

本质:完成某个特定功能的代码片段,并且可以被重复使用;
一个类中可以定义多个方法;方法体中不能再定义方法;(写程序记得剥离方法)
定义: [修饰符列表] 返回值类型 方法名(形参列表)

修饰符列表:可选,非必须。 public static
有static关键字,调用方法:类名.方法名(实参) //本类中的方法则可以省略类名.
只定义不调用则不会执行,JVM也不会分配运行所属的内存空间

public class Main { //Main是类名,定义公开的类,源文件名也必须是Main.java

内存分配

JVM的主要内存空间:
方法区:
代码片段,只有一份但可以反复调用
局部变量的声明
·方法代码属于.class字节码文件的一部分,在类加载时放到方法区,因此方法区最先有数据
(类的信息,字节码信息,代码片段,静态变量)
堆内存: 通过new运算符创建的对象,以及对象的实例变量
栈内存: 调用方法时分配的独立活动场所,压栈;方法结束执行,弹栈(栈的活动最频繁);
局部变量运行时在栈中存储。
所有方法执行都会压栈

画内存图:

推算结果、调试程序

空指针异常:

前提:空引用(=null)访问 “实例” 相关的数据(实例变量+实例方法)时
对象没有任何引用指向它,被GC(主要针对堆内存)回收了

静态的变量不会出现。???

重载机制:

功能相似时,方法名相同,宛如在调用同一个方法
条件:在同一个类中;方法名相同;参数列表不同(数量、类型、顺序)
和返回值类型无关

方法递归

递归必须有结束条件,否则会栈内存溢出;
即使有正确结束条件,也可能因为递归太深造成栈内存溢出;
递归很耗费栈内存,尽量不用

调用时的参数传递:和类型无关,都是传递变量中保存的"值"

构造方法

作用:创建对象、实例变量的初始化(创建对象并为对象的属性赋值)
实例变量么有手动赋值,系统会赋默认值

如何调用构造方法:使用new 构造方法名(实参)

构造方法结构: [修饰符列表] 构造方法名(形参列表){构造方法体}
----比普通方法少了返回值类型
public ,构造方法名和类名要一致。

当类没有提供任何构造方法,系统会默认提供一个无参数的构造方法(缺省构造器)
若有构造方法了则不会再提供无参构造,因此建议手动写出无参构造。

构造方法可以重载

static 关键字

1、static修饰的都是类级别的,整个类一样的属性建议定义为static
2、所有static修饰的都是用“类名.”访问

{
//实例都需要new对象,"引用."
实例变量
实例方法
//"类名."
静态变量
静态方法
}

静态和实例

1、静态方法
带有static的方法:
通过“类名.”的方式调用

静态方法不能直接访问实例变量,可以在方法里new一个对象后访问

2、实例方法
没有static的方法:
(对象方法,对象级别的方法)
需要先new对象,通过“引用.”的方式访问

方法体中访问实例变量—>一定是实例方法
大部分情况下,工具类的方法—>一般都是静态方法

变量:
方法体中:局部变量(栈)
方法体外:成员变量 【根据带不带static】----实例变量(堆)和静态变量(方法区)

实例变量: 一个对象一份的特征。一定需要使用“引用.”访问。(在构造方法执行时内存空间才会开辟)

静态变量: 在类加载时初始化,不需要new对象就开了空间,存储在方法区。当类里的所有对象的某个属性都一样,建议定义为类级别的特征。
建议使用“类名.”访问,“引用.”也可以用但容易令程序员混淆

静态代码块
特点:类加载时执行,并且只执行一次。在main执行前执行,自上而下的顺序执行。
(静态变量也是在类加载时执行,时间相同,靠代码顺序决定先后。如果变量代码在上面,则可以引用静态变量。)

作用:不常用,是一个特殊的时机–“类加载时机”,在xxx时间,哪个类加载到JVM当中了,这些记录日志的代码写到静态代码块中。

static{

}
public static void main(){
}

·实例语句块
语法: 大括号括住
只要构造方法执行,在构造方法前自动执行
“对象构造时机”,可以把构造方法前面相同的代码放里面

面向对象与面向过程

面向过程:注重步骤,主要是每一步的因果关系,
缺点:一个因果关系有问题,则系统都会出问题,代码间耦合度太高–>扩展能力差
优点:小型项目开发效率高,

面向对象: 把每一个小单元都看作一个对象,让它们进行协作
OOA:面向对象分析
OOD:面向对象设计
OOP:面向对象编程
三大特点
封装、继承、多态,三个特点一环扣一环,有了封装这个整体的概念后,对象之间产生了继承,然后才有方法覆盖和多态

软件开发原则
OCP(对扩展开放,对修改关闭):
目的:降低程序耦合度,提高程序扩展力
面向抽象编程,不建议面向具体编程

类和对象:
类:抽象概念,是一个模板,描述了所有对象的共同特征
类 = 属性(状态)(成员变量)+方法(动作)

对象(实例):实际存在的个体,是通过类创建出的
类–【实例化】–>对象
对象–【抽象】–>类

eg:
public class Student{
String name;
int num;
}

Student xxx = new Student();
变量类型 变量名 = 学生类创建出的一个对象(new 类名)
xxx:这个局部变量叫引用,它有一个地址指向了堆内存
int i = 10;

Student.name是错误的,不能用类名访问,必须先创建对象再访问

引用和对象:引用是存储对象内存地址的一个变量;对象是堆里new出来的
引用不一定是局部变量,因为也可能是在堆里的,成员变量/实例变量都可能是引用

面向对象的三大特征:封装–>继承–>多态

封装:

作用:保证内部结构的安全;屏蔽复杂,暴露简单
如何封装:
1、属性私有化(private,该数据只能在本类中访问)
2、1个属性对外提供两个入口:get和set
可以在set方法中设立关卡保证安全性

//get方法: 无static,都是实例方法,调用需要先new对象
//写的时候要按照要求
public 返回值类型 get+属性名首字母大写(无参){
	return xxx;
}
//set方法:
public void set+属性名首字母大写(有1个参数){
	xxx = 参数;
}

要 养成封装的好习惯

this 关键字

this是个变量,是个引用,这个引用指向自身的地址
this保存当前对象的内存地址,指向自身
this 代表“当前对象”,存储在堆内存中对象的内部

可以在实例方法和构造方法中。
为什么不能使用在静态方法中:静态方法的调用不需要对象
语法:“this.”“this()”
this.一般可以省略的
构造方法中区分局部变量和实例变量,这时不能省略。

this(实际参数1,参数2,参数3);–>只能放在构造方法第一行
通过构造方法1调用本类的其他构造方法2,可以做到代码复用。

super关键字

super代表的是当前对象this的父类型特征(是继承父类型的子类型的特征)

表示通过子类的构造方法调用父类的构造方法

可以在实例方法和构造方法中。
不能使用在静态方法中
语法:“super”“super()”
super.一般可以省略的
super.不能省略:父类子类有同名属性/方法,想在子类中访问父类的同名属性/方法时

super(实际参数1,参数2,参数3);–>只能放在构造方法第一行
通过构造方法1调用父类的其他构造方法2,可以做到代码复用。
目的:创建子类对象时,先初始化父类特征

当构造函数第一行没有this()和super()时,默认会有super()
默认有super()所以如果写了有参构造方法一定要手写无参的
this和super不能共存
无论怎么折腾,父类的构造方法都会先执行

构造方法执行过程中一连串调用了父类的构造方法,实际上对象只创建了一个

**super(实参)的作用:**初始化当前对象的父类型特征,并不是创建新对象,实际上对象只有一个。

//super不是引用,不保存内存地址,不指向任何对象,只代表当前对象内部中的父类型的特征

栈的数据结构

super的语法:
super.属性名 访问父类属性
super.方法名(实参) 访问父类的方法
super(实参) 调用父类构造方法

继承

基本作用:子类继承父类,代码可以复用
主要作用:有了继承,才有后期的方法覆盖和多态
什么时候使用: 可以用“is a ”来描述的,都可以继承,其他的即使有重复代码也要根据前面的准则。

相关特性:
1、B类继承A类,则A类为超类(superclass)、父类、基类,B类为子类(subclass)、派生类、扩展类

class A{}
class B extends A{}

2、只允许单继承,不允许多继承

class E extends A,B//这是错的

class X{}
class Y extends X{}
class Z extends Y{}//Z间接继承了X,这个OK

3、子类继承父类,除了构造方法不能继承其他都可以,但私有的属性无法在子类中直接访问。

4、所有类没有显示继承的,都默认继承Object类,是根。

5、缺点:子类继承父类后,使代码的耦合度增高

//反例,不能继承
class Custome{
String name;
}
class Product{
String name;
}
class Product extends Custome{
}

extends
除了构造方法都会继承,继承过来的就是自己的方法了

子类可以出现和父类一样的同名变量和属性

方法覆盖

方法覆盖(方法重写) override、overwrite:

【和重载overload区分:功能相似,在同一个类里,方法名相同,形参不同】

使用的场景:
子类继承父类后,继承过来的方法无法满足当前子类的业务需求,子类把继承到的方法重写

条件:
1、两个类有继承关系
2、重写后的方法和之前的方法具有相同的返回值类型、方法名、形参列表。
3、访问权限不能更低,可以更高。
4、重写后的方法不能比之前抛出更多异常,可以更少

注意事项:
只针对方法,和属性无关
私有方法不能覆盖
构造方法不能被继承,也不能覆盖
只针对实例方法,静态方法覆盖没有意义----因为静态方法不需要对象,多态方法和对象有关,即使在子类里重写了也还是用父类的方法。

//建议重写时将父类的方法复制粘贴

没有多态机制,方法覆盖可有可无

多态

1、两种类型之间有继承关系

向上转型(upcasting):子–>父(自动类型转换的意思)
向下转型(downcasting):父–>子(强制类型转换,需要加强制类型转换符)
父类型的引用指向子类型的对象【当需要调用子类中特有的方法时使用】

public class Animal{

}

public class Cat extends Animal{

public void catchMouse(){
}
}
public class Bird extends Animal{

}
//向上转型
Animal a4 = new Cat();
编译时是Animal,运行时是Cat,表面上是Animal,实际是Cat

//向下转型
Animal a5 = new Cat();
Cat x = (Cat)a5;
x.catchMouse();

//向下转型的风险
//类型转换异常!!!
//cat是animal的子类,编译阶段ok
//运行时堆实际创建的是bird,而运行过程中拿bird转换成cat就不行,因为他们没有继承关系
Animal a6 = new Bird();
Cat y = (Cat) a6;
y.catchMouse();

避免classCastException

运算符instanceof
运行阶段动态判断引用指向的对象类型
(向下转型时一定要使用!!!)

//c是引用,保存内存地址指向了堆中的对象
c instanceof Cat //结果为true或false,

if(a6 instanceof Cat){
	Cat y = (Cat) a6;
	y.catchMouse();
}

2、什么是多态: 父类型引用指向子类型的对象,包括编译阶段和运行阶段。
编译阶段:绑定父类的方法
运行阶段:动态绑定子类型对象的方法

3、多态的作用
降低程序耦合度,提高扩展力

final

1、final修饰的类无法继承
2、final修饰的方法无法覆盖
3、变量只能赋值一次
4、引用一旦指向某个对象,则不能再重新指向其他对象,但该引用指向的对象内部的数据是可以修改的
5、实例变量必须手动初始化,不能采用系统默认值
6、实例变量一般和static联合使用,称为常量。常量名全部大写

public static final double PI = 3.1415;

抽象类

1、定义:在class前添加abstract关键字
2、无法实例化、无法创建对象
3、final和abstract无法联合使用,是对立的
4、子类可以是抽象类或非抽象类
5、有构造方法,供子类所使用
6、抽象类中不一定有抽象方法,抽象方法一定出现在抽象类中
7、抽象方法的定义

public abstract void doSome(){}

8、非抽象类继承抽象类,必须把抽象类中的抽象方法进行覆盖、重写、实现。

接口

基础语法
1、接口是一种引用数据类型,编译之后也是一个class字节码文件
2、接口是完全抽象的,是特殊的抽象类
3、接口定义

[修饰符列表] interface 接口名()

4、接口和接口之间支持多继承
一个类可以实现多个接口,类似于多继承。
都是父类型引用指向子类型对象

interface X{}
interface Y{}
interface X extends X,Y{}

class C implements X,Y{}

5、接口中只包含两部分:常量、抽象方法
6、所有元素都是public修饰的
7、接口中的抽象方法定义可以省略public abstract 修饰符,常量的public static final 可以省略
8、方法都是抽象方法,都不能有方法体
9、非抽象类实现接口,要将接口中的所有方法重写!
10、一个类可以实现多个接口
11、extends和implements可以共存,implement在后面
12、使用接口时可以使用多态(父类型引用指向子类型对象)

类和类之间叫继承,类和接口之间叫实现(但也可以看作是继承)
继承:extends关键字 实现:implements关键字

(接口之间没有继承关系也可以进行强制转换,但运行时可能出现classCastException异常。向下转型还是在转型之前要加if(instanceOf)进行判断。)

调用其他接口中的方法需要进行接口转型

非抽象类实现接口,要将接口中的所有方法重写!
新的方法不能有更低的访问权限:如之前有public 现在没有,就会报错。
public权限最高。

在开发中的作用
和多态的作用类似
多态:面向抽象编程,不面向具体编程,降低程序的耦合度,提高程序的扩展力
接口:面向接口编程,降低耦合度,提高扩展力。接口的使用离不开多态机制。

//class里面凡是可以用has a 来描述的,都以属性的方式存在,属性可以是基本类型和引用类型

类型和类型之间的关系

is a :继承关系
cat is a animal

A extends B

has a :关联关系,通常为属性
I have a pen

A{
B b;
}

like a :实现关系,类实现接口
cooker like a foodmenu

A implements B

抽象类和接口的区别

抽象类是半抽象的
接口是完全抽象的

抽象类中有构造方法
接口没有构造方法

接口和接口之间支持多继承
类和类之间只能单继承

一个类可以同时实现多个接口
一个抽象类只能继承一个类(单继承)

接口中只允许出现常量和抽象方法

接口使用的比抽象类多
接口一般都是对“行为”的抽象

包机制 package和import

包机制的作用: 方便程序管理,不同功能的类分别放在不同的包下
package怎么用:
package是关键字,后面加包名,只允许出现在Java源代码的第一行。
命名规范
公司域名倒序+项目名+模块名+功能名

import
将需要的类导入

使用:import + 完整类名

什么时候使用:
A类中使用B类
A,B不在同一个包下时使用

访问控制权限

public:任何位置都可以访问
protected:只能在本类、同包、子类中访问
默认:只能在本类、同包下访问
private : 只能在本类中访问

集合

集合是一个容器,一个载体,一个对象,可以一次容纳多个对象。

集合不能存储基本数据类型和对象,存储的都是引用 ,对象的内存地址。

每个不同集合的底层都有不同数据结构,往不同集合中存储数据相当于往不同的数据结构中存储。(数据结构–数据的存储结构)。

所有集合类和接口都在 java.util.*包下。

需要掌握怎么使用、在什么情况下选择哪一种合适的去使用

//创建一个集合的三种方式
new ArrayList() :底层是数组
new LinkedList() : 底层是链表
new TreeSet()  : 底层是二叉树

集合有两大类:
单个元素–超级父接口:Collection

集合的继承结构图:
在这里插入图片描述
在这里插入图片描述
键值对–超级父接口:Map

Map集合的key都是无序不可重复的,Map和set集合存储元素相同

在这里插入图片描述
元素的特点
1、list集合:
有序可重复
(有序:存进去和取出来的顺序相同,有从0开始的下标)
(可重复:存进去1后,还可以再存1)
2、set集合:
无序不可重复
(无序:存和取的顺序不一定相同,没有下标)
3、SortedSet:
元素自动按照大小排序的,无序不可重复

总结所有的实现类:
AraryList:底层是数组
LinkedList:底层是双向链表
Vector:数组,线程安全
HashSet:HashMap,放到HashSet集合中的元素等同于放到HashMap集合key部分
TreeSet:TreeMap,放进去的元素等同于放到TreeMap集合key部分
HashMap:哈希表
Hashtable:哈希表,线程安全
Properties:线程安全,key和value只能存储字符串String
TreeMap:底层是二叉树,key可以按照大小顺序排序

Collection中存放什么元素

没有使用泛型–>Object的所有子类型
使用了泛型 --> 某个具体类型

不能直接存储基本数据类型,不能存储Java对象,只存储对象的内存地址

Collection的常用方法

boolean add(Object e);
int size()
void clear()
boolean contains(Object o) //底层调用equals方法来判断集合中是否包含某个元素的
boolean remove(Object o) //底层也调用equals方法,所以如果放进两个相同的字符串对象,remove后两个都删除
boolean isEmpty()
Object[] toArray()

//放在集合里的类型一定要重写equals方法

在这里插入代码片

在这里插入图片描述
迭代器对象有两个方法:hasNext和next


Collection c = new ArrayList();//后面的集合无所谓,主要看前面Collection的接口如何遍历
//第一步,获取集合对象的迭代器对象Iterator
Iterator it = c.iterator();
c.add("abd");
c.add(100);
c.add(new Object());
//第二步,通过迭代器对象开始迭代/遍历集合
while(c.hasNext()){
Object obj = it.next();
}

异常

异常处理机制的作用:
程序执行时出现不正常的情况,java会把异常信息打印输出到控制台。
将程序修改后,增加其健壮性

异常以什么形式存在:以类的形式存在,出现异常就会new一个异常对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值