java资料



方法区 :存方法,静态数据

匿名对象
没有变量名的对象 匿名对象

new Car();

this 代表本类对象,代表它所在函数对象的引用。哪个对象在调用this所在的函数,this就代表哪个对象

构造函数
在构造函数相互调用的时候只能用 this(参数 ) 并且要在第一行

静态 static 不能修饰局部变量,随类的加载而加载
可以让对象调用也可以用类名调用

静态代码块 随着类的加载而执行,只执行一次 一般给类初始化

static{

}

构造代码块,在默认构造函数之后执行,在调用相应的构造函数之前执行

{

}

final
可修饰类 方法 变量
修饰的类不能继承
修饰的方法不能覆盖
修饰的变量是一个常量,只能赋值一次
内部类只能访问被final修饰的局部变量

抽象类 abstract 可以有抽象方法和普通方法
抽象方法一定在抽象类中
抽象类不能new对象
如果子类只复写抽象类的部分抽象方法,子类还是抽象类

对象实例 instanceof 类型

多态
成员函数特点
成员函数在多态调用的时候,编译看左边, 运行看右边
注意:静态成员函数在多态调用的时候看左边
例:

Fu f = new Zi();
f.fun();//当 fun 是static方法 这样访问的时候 会直接访问父类的方法

这是因为 这是静态方法可以通过类名直接访问 而左边 恰恰就是父类的 类名

在多态中,成员变量的特点
无论编译和运行,都参考左边(引用型变量所属的类)

Fu f = new Zi();
f.num;//这里调用的是父类的num

内部类
创建内部类对象

Outer.Inner in = new Outer().new Inner();

一个类可以私有
内部类可以作为其他类的私有成员

class Outer{

    private int x = 3;
    class Inner{
        int x = 5;

        //this.x 内部类的 x
        //Outer.this.x 外部类的 x
    }

}

静态内部类 只能直接访问外部类的static成员
创建静态内部类

Outer.Inner in = new Outer.Inner();
in.func();//访问静态内部类的非静态成员

//访问静态内部类的静态成员
Outer.Inner.func();

静态内部类无法从外部类引用 非静态成员,只能访问 外部类的 静态成员

非静态内部类不能声明 静态成员,如果内部类是静态的 类成员必须是静态的

外部类的静态成员函数 不能访问非静态内部类,只能访问静态内部类

内部类定义在局部的时候(就是把内部类定义在外部类的方法里面)

1、不可以被成员修饰符修饰(public private …)
2、可以直接访问外部类中的成员,因为还持有外部类的引用
但是不可以访问它所在的局部中的变量,除非该局部变量是用 final 修饰的局部变量
3、内部类定义在局部不能用static。

匿名内部类:
1、匿名内部类其实就是内部类的简写格式
2、定义匿名内部的前提:内部类必须是继承一个类或者实现接口
3、匿名内部类的格式:new 父类或者接口(){定义子类内容}
4、
例:

abstract AbsDemo{
    abstract void show();
}

class Outer{

    public void func(){
        //匿名内部类
        new AbsDemo{
            void show(){
                System.out.println("show");
            }
        }.show();
    }
}

面试题
若一个想创建一个内部类简单的运行一个方法这个内部类 没有父类 也没有接口
解:用Object类 的匿名内部类

new Object(){

    void func(){
    }
}.func();

异常
throws和throw的区别
throws使用在函数上 throws后面跟异常类,可以跟多个,用逗号分开
throw使用在函数内 throw 后面跟的是异常对象

Exception 中有一个特殊的子异常RuntimeException 运行时异常
如果在函数内抛出该异常,函数上可以不用声明,编译一样通过(直接用throw 不用 在函数上用throws声明)
如果在该函数上声明该一样,调用者不用try-catch 处理 编译一样通过

自定义异常时 如果该异常的发生,无法再继续进行运算就让自定义异常继承RuntimeException

多线程

创建新线程有三中方法

一、继承Thread类创建线程类

(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。

(2)创建Thread子类的实例,即创建了线程对象。

(3)调用线程对象的start()方法来启动该线程。让虚拟机去调用线程的 run(), 如果用户直接调用run() 方法并不会有新的线程

public class FirstThreadTest extends Thread{  
    int i = 0;  
    //重写run方法,run方法的方法体就是现场执行体  
    public void run()  
    {  
        for(;i<100;i++){  
        System.out.println(getName()+" ---- "+i);  

        }  
    }  
    public static void main(String[] args)  
    {  
        for(int i = 0;i< 100;i++)  
        {  
            System.out.println(Thread.currentThread().getName()+"  : "+i);  
            if(i==20)  
            {  
                new FirstThreadTest().start();  
                new FirstThreadTest().start();  
            }  
        }  
    }  

}  

上述代码中Thread.currentThread()方法返回当前正在执行的线程对象。GetName()方法返回调用该方法的线程的名字。

二、通过Runnable接口创建线程类

(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

(3)调用线程对象的start()方法来启动该线程。

示例代码为:

public class RunnableThreadTest implements Runnable  
{  

    private int i;  
    public void run()  
    {  
        for(i = 0;i <100;i++)  
        {  
            System.out.println(Thread.currentThread().getName()+" "+i);  
        }  
    }  
    public static void main(String[] args)  
    {  
        for(int i = 0;i < 100;i++)  
        {  
            System.out.println(Thread.currentThread().getName()+" "+i);  
            if(i==20)  
            {  
                RunnableThreadTest rtt = new RunnableThreadTest();  
                new Thread(rtt,"thread1").start();  
                new Thread(rtt,"thread2").start();  
            }  
        }  

    }  

}  

三、通过Callable和Future创建线程

(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。

(2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。

(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。

(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

实例代码:

public class CallableThreadTest implements Callable<Integer>  
{  

    public static void main(String[] args)  
    {  
        CallableThreadTest ctt = new CallableThreadTest();  
        FutureTask<Integer> ft = new FutureTask<>(ctt);  
        for(int i = 0;i < 100;i++)  
        {  
            System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);  
            if(i==20)  
            {  
                new Thread(ft,"有返回值的线程").start();  
            }  
        }  
        try  
        {  
            System.out.println("子线程的返回值:"+ft.get());  
        } catch (InterruptedException e)  
        {  
            e.printStackTrace();  
        } catch (ExecutionException e)  
        {  
            e.printStackTrace();  
        }  

    }  

    @Override  
    public Integer call() throws Exception  
    {  
        int i = 0;  
        for(;i<100;i++)  
        {  
            System.out.println(Thread.currentThread().getName()+" "+i);  
        }  
        return i;  
    }  

}  

创建线程的三种方式的对比

采用实现Runnable、Callable接口的方式创见多线程时,优势是:

线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。

在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

劣势是:

编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

使用继承Thread类的方式创建多线程时优势是:

编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势是:

线程类已经继承了Thread类,所以不能再继承其他父类。

getName() 获取线程名称
setName() 设置线程名称(构造函数通过super(“xxx”) 也能设置名字)

同步代码块

synchronized(对象){//对象是所需要的锁  没有特殊情况 一般用 this 锁

    需要同步的代码
}

同步函数 ,同步函数函数的锁用的是this 锁,
若同步函数是静态的(静态进内存时 内存中没有本类对象 但一定有该类对应的字节码文件对象) ,类名.class 该对象的类型是Class
静态的同步方法 使用的锁是该方法所在类的字节码文件对象。类名.class
当在静态方法中需要写同步代码块 需要用 类名.class 的锁

public synchronized void add(int i){

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值