JAVA基础笔记——对象、异常、static总结-创新互联
- 一、对象
- 1.1 对象的创建
- 1.2 类中的构造器/构造方法
- 1.3 对象建立、内存分析
- 1.3.1 堆
- 1.3.2 栈
- 1.3.3 方法区
- 1.3.4 对象建立过程中内存分配分析
- 1.4 对象的特性
- 1.4.1 封装
- 1.4.2 继承
- 1.4.2.1 继承的使用
- 1.4.2.2 Object类
- 1.4.2.3 this/super
- 1.4.2.4 方法重写
- 1.4.3 多态
- 1.4.3.1 多态的使用
- 1.4.3.2 instanceof
- 1.4.3.3 类型转换
- 1.5 final
- 1.5.1 修饰类
- 1.5.2 修饰方法
- 1.5.3 修饰局部变量
- 1.5.4 修饰成员变量
- 1.6 抽象类/方法
- 1.7 接口
- 1.8 内部类
- 1.8.1 成员内部类
- 1.8.2 静态内部类
- 1.8.3 局部内部类
- 1.8.4 匿名内部类
- 二、static的总结
- 2.1 类中的static
- 2.2 静态导入包
- 三、异常
- 3.1 异常定义和体系结构
- 3.2 捕获异常
- 3.3 抛出异常
- 3.4 自定义异常
一、对象
打补丁:类的命名应遵守首字母大写和驼峰原则
1.1 对象的创建tips:
- 本质:类是抽象的,对象是类的具体化;以类的方法组织代码,以对象的方式封装数据
- 创建:使用new创建对象,除了分配内存空间外,会给建立好的对象进行默认的初始化或者调用类中的构造器。
- example:新建学生类,显示默认的初始化成员
1)学生类 stu.java
public class stu {//属性
String name;
int age;
//方法
public void setAge(int stuAge){this.age=stuAge;
}
public int getAge(){return this.age;
}
}
2)运行代码 application.java
public class application {public static void main(String[] args) {//new实例化类
stu stuList=new stu();
int stuAge=stuList.getAge();
System.out.println("年龄:"+stuAge);
}
}
3)测试结果
tips:
- 作用:用于对象初始化
- 显式和隐式构造方法:
1) 当没有显式定义任何构造方法时,系统默认一个构造方法,给所有成员赋默认值;
2)当显式定义有参构造方法后,无参构造方法也必须显式定义,否则无参实例化会报错;
3)必须写无参构造方法,避免父类只有有参构造方法导致子类的构造方法报错(原因:父类没有可调用的无参构造方法,详见继承) - 特点:
1)构造方法名与类名一致;
2)必须没有返回值,特别是不可以写void - idea的构造方法(读写成员变量等)自动生成快捷键:
Alt+Insert,如果insert在键盘中与其他按键共建(如跟F12或者Delete),则快捷键为Fn+Alt+Insert
1)按下快捷键,选择生成“构造函数”
2)长按ctrl,通过鼠标单击选择(取消)初始化的字段,ctrl+A全选,此处需要注意,当显式有参构造方法后,无参构造方法也需要显式定义
3)生成代码:
5.example:新建学生类,使用有参和无参构造方法
1)学生类 stu.java
public class stu {//属性
String name;
int age;
double height;
//方法
public stu() {System.out.println("无参构造方法被调用");
}
public stu(String name, int age,double height) {this.name = name;
this.age = age;
this.height=height;
System.out.println("有参构造方法被调用");
}
public int getAge() {return age;
}
public void setAge(int age) {this.age = age;
}
}
2)运行代码 application.java
public class application {public static void main(String[] args) {//new实例化类
stu stuNull=new stu();
stu stuList=new stu("liqour",21,180);
int stuAge=stuList.getAge();
System.out.println("年龄:"+stuAge);
}
}
3)测试结果
tips:
- 存放new的对象和数组
- 可以被所有的线程共享
tips:
- 存放基本变量类型和具体数值
- 引用对象的变量和该引用变量在堆里的地址
tips:
- 是堆中一个特殊的区域
- 可以被所有的线程共享
- 包含了所有的class类和static变量/方法
tips:
- example:一个学生类,建立两个对象stuA和stuB。
1)学生类 stu.java
public class stu {//属性
int age;
String name;
//方法
public stu() {System.out.println("无参构造方法被调用");
}
public stu(int age, String name) {this.age = age;
this.name = name;
}
public int getAge() {return age;
}
public void setAge(int age) {this.age = age;
}
}
2)运行代码 application.java
public class application {public static void main(String[] args) {//new实例化类
stu stuA=new stu(21,"liquor");
int stuAge= stuA.getAge();
System.out.println("A年龄:"+stuAge);
stu stuB=new stu(20,"gin");
stuAge= stuB.getAge();
System.out.println("B年龄:"+stuAge);
}
}
3)内存分配
tips:
1.程序设计需要追求高内聚,低耦合。类的内部数据操作细节自己完成,外部不可干涉;尽量少向外部暴露。
2.方法:属性定义为私有private,通过get/set获取/修改(快捷键Alt+Fn+Insert)
tips:
- 本质:对一批类的抽象,是类之间的关系,子类(派生类)继承成父类(基类)
- 目的:较少重复的代码,提高可维护性
- 单继承和多继承:
JAVA只有单继承,没有多继承(C++)
单继承:一个子类只能继承一个父类,java
多继承:一个子类可以继承多个父类,c++ - 意义: 子类拥有父类非private的属性和方法(私有private无法被继承);子类在父类的基础上进行拓展(即拥有自己的方法)
- 语法结构:在子类申明时使用关键字extends
public class 子类名 extends 父类名
{子类内容;
}
- 在类的方法中调用本身的属性/方法,使用关键字this
在类的方法中调用父类的属性/方法,使用关键字super - 父类子类的构造方法
1)系统默认在子类构造方法的最初隐式调用父类的无参构造方法,若需要在子类构造方法中显式调用父类的有参构造方法,则调用必须写在第一行,调用语句:super(传递给父类构造方法实参表);
2)父类一定要显式写明无参构造方法,因为子类的构造方法中,若没有显式调用父类有参的构造方法,系统默认在代码最初隐式调用父类的无参构造方法。如果父类只显式声明了有参构造方法,会导致系统默认的父类的无参构造方法失效(详见类的建立),使得子类在隐式调用时报错。
example:
1)Person类
public class Person {//属性
private String name;
private int age;
//无参
public Person() {System.out.println("Person的无参构造方法被调用");
}
//有参
public Person(String name, int age) {this.name = name;
this.age = age;
}
public int getAge() {return age;
}
public void setAge(int age) {this.age = age;
}
public String getName() {return name;
}
public void setName(String name) {this.name = name;
}
}
2)Stu类
public class Stu extends Person{//属性
private String name;
//方法
//无参
public Stu() {//此处存在系统隐式调用的父类无参构造函数
System.out.println("Stu的无参构造方法被调用");
}
public String getName() {return name;
}
public void setName(String name) {this.name = name;
}
//有参
public Stu(int age, String name, String stuName) {//显式调用父类的有参构造函数
super(name,age);
//父类构造函数必须在第一行
this.name=stuName;
System.out.print("Person类的姓名:"+super.getName()+"\n");//取父类的非private方法
System.out.println("Stu类的姓名:"+this.getName());//调用本身
}
}
3)运行代码 Application.java
public class Application {public static void main(String[] args) {//子类无参构造
Stu stuA=new Stu();
//子类有参构造
Stu stuB=new Stu(21,"liquor","gin");
}
}
4)运行结果
tips:
- 在java中,所有的类都会自动继承Object类
- /******后续回来打补丁/
tips:
- super用于在类中调用父类的非private方法和属性;
- this用于在类中调用自身的方法和属性;
- super(实参表);用于调用父类的构造方法,在子类构造的第一行
- this(实参表);用于本类的构造,也需要在第一行,所以this()和super()调用构造方法都要求在第一行,不能同时出现在一个方法中
tips:
作用意义:由于父类的功能不满足子类的具体需要,子类对父类非私有、非静态的方法,重写内容
特性:
1)是继承之间,子类对父类操作
2)方法名和参数列表必须一致
3)子类重写的方法修饰符范围只能缩小不能扩大(public>protected>default>private)
4)重写会抛出异常,子类异常的范围可以缩小不能扩大IDEA快捷键:Ctrl+O或者在生成栏(Fn+Insert+Alt)中可以自动生成代码
重写方法中,父类会有标记(箭头向下)
子类会有标记(箭头向上)和注释 @Override方法是否静态(staitc)
方法状态 | 影响 |
---|---|
静态 | 静态方法的调用只和定义的左边的类型有关(非重写) |
非静态 | 当父类的引用指向子类(多态),非静态非私有的,调用子类的方法 |
tips:
- 动态编译,类型有可扩展性
- 一个对象的实际类型是确定的,但指向的引用类型可以不确定,如父类的变量new子类
- 父类的引用指向子类(多态),比如,若F是S的父类
F father=new S();
- 父类子类之间调用关系(假设F是父类,S是子类)
声明 | 调用范围 |
---|---|
子类变量new子类,S a=new S(); | 对象a能调用自己的方法或者从父类继承的非私有的方法 |
父变量new子类,F a=new S(); | 当子类S中有对父类F非私有非静态方法重写时,调用子类重写的方法;但是不可以调用子类独有的方法 |
特性:
1)多态只有方法,没有属性
2)多态是父类变量New子类,必须有父子关系,否则出现类型转换异常,报错:ClassCastException!动态的父类调用逻辑
1)首先看该方法能否被调用,即父类是否拥有该方法。某种方法(名)能否被调用,看等式的左侧类型是否包含该方法(即多态的父类变量不可以调用子类独有的方法,此处要与继承区分,继承是子类可以调用父类所有非私有的方法),见example1。
2)其次看该方法是否被子类重写,若该方法(非私有非静态)被子类重写,则动态的父类调用子类的方法。见example2。example1:
父类Person独有非静态非私有方法fatherTest(),可以被子类变量继承调用;子类Stu独有方法不能被父类变量调用
1)父类Person
public class Person {private String name;
private int age;
public Person() {}
public Person(String name, int age) {this.name = name;
this.age = age;
}
public void fatherTest(){System.out.println("fatherTest");
}
}
2)子类Stu
public class Stu extends Person{//方法
public Stu() {}
public Stu(int age, String name) {//显式调用父类的有参构造函数
super(name,age);
}
public void sonTest()
{ System.out.println("SonTest");
}
}
3)运行代码(报错截图) Application.java
- example2:
父类Person,子类Stu,对test()重写,testSta()作为静态方法参照
1)父类Person
public class Person {private String name;
private int age;
public Person() {}
public Person(String name, int age) {this.name = name;
this.age = age;
}
public void test() {System.out.println("Person->getName");
}
public static void testSta() {System.out.println("Person->test");
}
}
2)子类Stu
public class Stu extends Person{//方法
public Stu() {}
public Stu(int age, String name) {//显式调用父类的有参构造函数
super(name,age);
}
@Override
public void test() {System.out.println("Stu->getName");
}
public static void testSta() {System.out.println("Stu->test");
}
}
3)测试代码 Application.java
package oop;
public class Application {public static void main(String[] args) {Stu stuA=new Stu();
Person stuB=new Stu();//重写
Person stuC=new Person();
//非静态
stuA.test();
stuB.test();
stuC.test();
//静态
stuA.testSta();
stuB.testSta();
stuC.testSta();
}
}
4)运行结果
tips:
- 作用:判断类之间是否存在父子/祖先子孙关系
- 语法结构:A、B、C为类
A relVar=new B();
boolean result=relVar instanceof C;
- 原型链:从该类型向上回溯所有的祖先类
比如,对于example中的配图,Teacher的原型链为Teacher->Person->Object;Person的原型链为Person->Object - 判断方法:
1)是否通过编译:若C在A的原型链或者是以A为根的树上(以A为源头,向下找树,向上找链),则instanceof可以通过编译
2)是否为True:以B为起点,向上回溯原型链(即B的所有父类、祖父类和本身) - example:标红经过结点符合要求
1)判断以下类的关系:
2)Object ob=new Stu();
可编译:
结果为True:
运行结果:
3)Person per=new Stu();
可编译:
结果为True:
运行结果:
4)Person person=new Person();
可编译:
结果为True:
测试结果:
tips:
1.方便方法调用,用于解决父类引用指向子类时,又希望调用子类独有方法的情况。
转换方向 | 方法 | 应用 |
---|---|---|
父类转换子类 | 强制转换 | 解决父类引用指向子类时,解决多态存在父类变量不可以调用子类独有的方法的问题 |
子类转换父类 | 自动转换 | 见多态 |
- 语法结构:F为父类,独有方法fatherTest();S为子类,独有方法sonTest()
F relVar=new S();
((S) relVar).sonTest();
1.5 final1.5.1 修饰类参考整理自Java中final关键字
- 作用:终止继续向下继承
- 语法结构:
public final class 类名{}
- 特性:不能与abstract共用
tips:
- 作用:禁止该方法被覆盖重写
- 语法结构:
public final 返回值类型 方法名(形参表){}
- 特性:不能与abstract共用
tips:
- 对于基本变量,变量的数值不可改变
- 对于引用变量,变量中存储的地址不可改变(即不可以换另一个对象),但地址指向的对象本身内容可变
tips:
- 对于成员变量,修饰后变量的值也不可以改变,即不可以再调用set()函数修改
- 使用final后需要显式赋值,系统不再赋默认值
- 对于final修饰的成员变量显式赋值,可通过直接赋值或者构造方法赋值,其中,构造方法要保证所有重载的方法都对该变量赋值。
tips:
- 修饰符abstract,可以用于修饰类或者方法
- java的抽象类只能单继承,具有局限性
- 语法结构:
public abstract class 类名{public abstract void test();
}
- 抽象类中可以没有抽象方法,但是抽象方法的类一定要声明为抽象类
- 抽象类不能通过new来创建具体的对象,本质上是用于子类继承的
- 抽象方法只有方法的声明,没有方法的实现,本质上是用于子类实现的
- 子类继承了抽象类,要么实现抽象类的抽象方法,要么该子类也需要声明为抽象类,需要继续向下继承。
tips:
- 接口可以多继承,本质上是一种约束,不可以被实例化,没有构造方法
- 对比普通类、抽象类和接口
类别 | 特性 |
---|---|
普通类 | 具体实现方法 |
抽象类 | 具体实现方法和抽象方法都有,局限是只能单继承 |
接口 | 只有规范,不能写方法 |
- 声明接口的关键字是”interface",IDEA中标签为绿色的大写I
public interface 接口名{}
- 接口中的方法是隐式定义为public abstract的,常量隐式定义为public static final的,不可修改。
- 实现接口的类,必须要重写接口中的所有方法
- 实现接口的类增加关键字 implements;多继承时,接口名通过都好隔开
public class 类名 implements 接口名1,接口名2{}
1.8 内部类1.8.1 成员内部类简记科普,后续再打补丁
tips:
- 可以获得外部类的私有属性
- example:内部类Inner,外部类Outer,通过内部类调用外部类的私有属性
1)类的代码
public class Outer {private int id=10;
public Outer() {}
public Outer(int id) {this.id = id;
}
public void out(){System.out.println("外部类的方法");
}
public class Inner{public void in(){System.out.println("内部类的方法");
}
//内部类获得外部类的私有属性
public void getID(){System.out.println(id);
}
}
}
2)运行代码Application.java
package oop;
public class Application {public static void main(String[] args) {Outer outer=new Outer();//初始化外部类
Outer.Inner inner=outer.new Inner();//初始化内部类
inner.getID();
}
}
- 一个java类中可以有多个class类,但是只能有一个public class类
- 在其他class类中可以写测试代码(但最好用Application.java单独做一个文件)
tips:
1.静态内部类不能取外部类的私有属性,因为静态先生成
2.相比成员内部类,增加一个static修饰词
tips:
- 在外部类的方法中写内部类
- example:
public calss Outer{public void method(){class Inner{ public void in(0{ }
}
}
}
1.8.4 匿名内部类tips:
- 没有名字初始化类,不用将实例保存在内存中。
- example:
new Outer().out();
二、static的总结 2.1 类中的static
tips:
- 静态属性变量: 可以用对象名或者类名调用。主要用于多线程。
example:
1)Person类
public class Person {private String name;
public static int nom;
public Person() {}
}
2)测试代码Application.java
public class Application {public static void main(String[] args) {Person personVar=new Person();
int nom=personVar.nom;//对象名调用
nom=Person.nom;//类名调用
}
}
静态方法
在一个类中,非静态方法可以直接通过方法名调用静态方法;静态方法不可以直接调用非静态方法静态代码块
1)只会执行一次
2)语法结构
public class Person
{static{//静态代码块
}
}
3)example:静态代码块、匿名代码块、构造方法执行顺序:静态代码块执行一次,之后每次new新对象,执行匿名代码块和构造方法。
public class Teacher{{System.out.println("匿名代码块");
}
static{System.out.println("静态代码块");
}
public Teacher() {System.out.println("构造方法");
}
public static void main(String[] args) { Teacher per1=new Teacher();
System.out.println("***************");
Teacher per2=new Teacher();
}
}
2.2 静态导入包tips:
- 作用:调用时通过方法名random()直接调用,而不通过Math.random()
- 语法结构:
import static java,lang.Math.random;
三、异常
3.1 异常定义和体系结构简记科普,后续再打补丁
tips:
- 分类
名称 | 定义 |
---|---|
检查性异常 | 最具代表性的是用户错误或问题引起的异常,无法被遇见,在编译时不能被简单忽略 |
运行时异常 | 可能被程序员避免的异常,在编译时会被忽略 |
错误 | 错误不是异常,是脱离程序员控制的问题,如栈溢出,在编译时无法报错 |
- Java 把异常当初对象来处理 ,定义了一个基础类java.lang.Throwable作为所有异常的超类。
- 区分错误Error和异常Exception
1)Error:灾难性的致命错误,程序无法控制和处理,JVM一般会选择终止线程
2)Exception:通常情况是可以被程序处理的,并且在程序中应该尽可能的去处理。 - 异常的类型和大小关系
- 异常中重要的分支运行时异常,包含数组下标越界、空指针、算数异常、丢失资源、找不到类等,一般是由于程序逻辑错误引起的,从逻辑进度应该尽量避免可以在程序中选择捕捉,也可以不处理。
tips
- 捕获异常相关的关键字
关键字 | 用法 |
---|---|
try | 监控区域 |
catch | 捕获异常,括号内是希望捕获的异常类型 ,可以写多个catch捕获多个异常,要将异常类型最小的写在最前面,层层递进 |
finally | 无论是否捕获到异常都会执行,在try-catch-finally中,finally可以没有,但主要用于IO流时关闭资源 |
- 语法结构:
try{}catch( 异常类型 异常名称1){}catch(异常类型 异常名称2){}
finally{}
- IDEA捕获异常快捷键Ctrl+Alt+T,选中需要监管的语句,按下快捷键,选择try-catch-finally
tips:
- 抛出异常一般用于方法中,当该方法处理不了异常,可以将异常抛出
- 抛出异常关键字
关键字 | 作用 |
---|---|
throw | 在方法内 |
throws | 在声明方法时 |
- 语法结构
public void 方法名(形参表) throws 异常类型{//代码块
throw new 异常类型();
}
3.4 自定义异常tips:
Java内置异常类已经可以处理大部分情况,但用户可以通过继承Exception类来自定义异常。
自定义异常类步骤:
1)创建自定义异常类
2)在方法中通过throw抛出异常对象
3)如果在抛出异常的方法中处理异常,则使用try catch语句捕获处理;否则通过throws指明要抛出给方法调用者的异常
4)在方法调用处捕获并处理异常example:
1)自定义异常类myException
public class myException extends Exception{private int detail;
public myException(int detail) {this.detail = detail;
}
public String toString(){return "myException("+detail+")";
}
}
2)测试类test
public class test {static void test(int a) throws myException{System.out.println("传参为"+a);
if(a>10){throw new myException(a);
}
System.out.println("ok");
}
public static void main(String[] args) {try {test(1);
} catch (myException e) {System.out.println("myException=>"+e);
} finally {}
}
}
3)结果
a<=10
a>10
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页题目:JAVA基础笔记——对象、异常、static总结-创新互联
新闻来源:http://scjbc.cn/article/cshees.html