Java基础知识——个人笔记

1、熟悉封装、继承、多态、重载、重写等概念,并以实例进行说明

封装

封装就是将对象的属性和实现细节隐藏起来,并提供公共访问方式。
封装的好处:隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据,可以方便的加入存取控制语句,限制不合理操作。
实例:

public class Dog {
    //私有化属性
    private String name;
    private String sex;
    private String color;
    //封装字段
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getSex() {
        return sex;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }
}

继承

继承主要要用到这几个关键字:
1.extends关键字: 使用extends关键字,子类就拥有了父类的所有属性和方法(拥有不代表就能访问).
2.super关键字: 父类对象的引用,例如:super.name 就是调用父类的name 属性;super(name)表示调用父类的构造方法,传入那么参数,
继承需要注意的问题:
只允许单一继承,任何一个类,只有一个直接继承的父类.
继承层次太多的时候,代码也会显得非常混乱,最好控制继承的层次<=3;
final会显示禁止某个类被继承,表示最后一个类,不可被继承或者修改.。

多态

多态一个引用可能表现出多种形态,一个父类引用可以对应到不同的子类对象,不同子类对象具体的行为都会存在差异.

//创建子类
public class Shape {
    public void draw() {
        // 绘制
        // 对于 Shape 来说暂时啥都不画
    }
}

子类重写父类方法:
public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("○");
    }
}

public class Rect extends Shape {
    @Override
    public void draw() {
        System.out.println("□");
    }
}

public class Flower extends Shape {
    @Override
    public void draw() {
        System.out.println("♣");
    }
}

public class Test {
    public static void main(String[] args) {
        Shape shape=new circle();//向上转型
        shape.draw();
        shape=new Rect();
        shape.draw();
        shape=new Flower();
        shape.draw()
    }
    

结果:
在这里插入图片描述

方法重载(overload)

描述两个普通方法之间,名字相同,参数不同,和继承没有直接关系,和返回值无关;

方法重写(override)

必须是父类方法和子类方法之间,名字相同,参数也相同,和返回值无关,一般情况下在重写方法的时候尽量不要修改返回值的类型.

2、熟悉异常处理机制

java使用面向对象的方式来处理异常,它把程序中发生的每个异常分别封装到一个对象中,该对象包含有异常的信息.所有异常的根类是Throwable,Throwable又派生了两个子类,Error和Exception

Exception包括运行时期异常和编译期异常

运行时期异常的特点:
①方法定义中无需throws声明,调用者也无需try-catch处理此异常.
②运行时期异常一旦发生,需要程序人员修改源代码.(这些异常通常是由于逻辑错误引起的)
一般异常(编译时异常):
必须进行处理的异常,如果不处理,程序就不能编译通过,可以通过try…catch处理或用throws声明继续抛给上层调用方法处理

error:

Error错误通常没有具体的处理方式,程序将会结束运行。Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的。我们无法针对处理,只能修正代码。
常见的运行时异常有:
NullPointerException
ClassCastException
ArrayIndexOutOfBoundsException
ArithmeticException
IllegalArgumentException
IllegalStateException
异常处理时需要注意的问题:
①java异常处理用到了多态的概念,如果在异常处理过程中,先捕获了基类,然后在捕获子类,那么捕获子类的代码块永远不会执行.因此,在进行异常捕获时,正确的写法是先捕获子类,再捕获父类的异常信息
正确的写法

try{

}catch( SQLException e){

}catch(Exception){

}

②异常能处理就处理,不能处理就抛出.对于一般异常,如果不能进行行之有效的处理,最好转换成运行时异常抛出

3、熟悉多线程

一、线程的生命周期:

新建 :从新建一个线程对象到程序start() 这个线程之间的状态,都是新建状态;
就绪 :线程对象调用start()方法后,就处于就绪状态,等到JVM里的线程调度器的调度;
运行 :就绪状态下的线程在获取CPU资源后就可以执行run(),此时的线程便处于运行状态,运行状态的线程可变为就绪、阻塞及死亡三种状态。
等待/阻塞/睡眠 :在一个线程执行了sleep(睡眠)、suspend(挂起)等方法后会失去所占有的资源,从而进入阻塞状态,在睡眠结束后可重新进入就绪状态。
终止 :run()方法完成后或发生其他终止条件时就会切换到终止状态。

二、java多线程的几种实现方式:

1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程 (上一篇已经讲过了)

前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果
后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中

三、常用方法

Thread.yield():当前线程可转让cpu控制权,让别的就绪状态线程运行(切换)
Thread.sleep():使线程暂停执行一段时间的方法。
Thread.await():它也是一种使线程暂停执行的方法。
Thread.yield():该方法和sleep方法类似,也是Thread类提供的一个静态方法,可以让正在执行的线程暂停,但是不会进入阻塞状态,而是直接进入就绪状态。
join():在一个线程中调用other.join(),将等待other执行完后才继续本线程。
interrupte():中断线程

具体来说sleep()方法和await()方法的区别主要表现在以下几个方面?

1、原理不同
sleep()方法是Thread类的静态方法,是线程用来控制自身流程的,它会使线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,此线程会自动被唤醒。
例如:当线程执行报时功能时,每一秒钟打印出一个时间,那么此时就需要在打印方法前面加上一个sleep()方法,以便让自己每隔1s执行一次。
wait()方法是Object类的方法,用于线程间通信,这个方法会使当前拥有该对象锁的线程等待,直到其他线程调用notify()方法或者notifyAll()方法才会被唤醒,不过也可以给线程指定时间被唤醒。
2、对锁的处理机制不同
由于sleep()方法的主要作用是让线程暂停执行一段时间,时间一到则自动恢复,不涉及线程间通信,因此调用sleep()方法并不会释放锁。
wait方法则不同,当调用wait()方法后,线程会释放掉它锁占用的锁,从而使线程所在对象中的其他synchronized数据可被别的线程使用。
3、使用区域不同
由于wait()方法的特殊意义,因此它必须放在同步控制方法或者同步语句块中使用,而sleep()方法则可以放在任何地方使用
sleep()方法必须捕获异常,而wait()、notify()、notifyall()不需要捕获异常。在sleep的过程中,有可能被其他对象调用它的interrupt()、产生interruptedException异常。
由于sleep不会释放"锁标志",容易导致死锁问题的发生

sleep()和yield()方法有什么区别?

1、sleep()方法在给其他线程运行机会时不考虑线程的优先级。因此会给低优先级的线程运行的机会,而yield()方法只会给相同优先级或更高优先级的线程运行的机会。

2、 线程执行sleep()方法后会转入阻塞状态,所以执行sleep()方法的线程在指定的时间内肯定不会被执行,而yield()方法只是使当前线程重新回到就绪状态,所以执行yield()方法的线程有可能在进入到就绪状态后又立马被执行。

四、线程同步与锁。

同步方法1:
    同步函数:就是用synchronize关键字修饰的方法。因为每个java对象都有一个内置锁,当用synchronize关键字修饰方法时内置锁会保护整个方法,而在调用该方法之前,要先获得内置锁,否则就会处于阻塞状态。
同步方法2:
    同步代码块:就是拥有synchronize关键字修饰的语句块,被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。

五、死锁

进程A中包含资源A,进程B中包含资源B,A的下一步需要资源B,B的下一步需要资源A,所以它们就互相等待对方占有的资源释放,所以也就产生了一个循环等待死锁。
死锁形成的必要条件总结(都满足之后就会产生):
    ①、互斥条件:资源不能被共享,只能被同一个进程使用;
    ②、请求与保持条件:已经得到资源的进程可以申请新的资源;
    ③、非剥夺条件:已经分配的资源不能从相应的进程中强制剥夺;
    ④、循环等待条件:系统中若干进程形成环路,该环路中每个进程都在等待相邻进程占用的资源。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值