java基础回顾(一)


常用DOS命令

  • 回退一级目录:cd..

  • 回退到顶级目录:cd\

  • 清屏:cls

  • 退出:exit


java在DOS中编译和运行

  • 带包编译:文件根目录 javac 文件名.java

    • 例子:javac HelloWorld.java
  • 带包运行:包根目录 java 包名.类名 参数1 参数2

    • 例子:java com.sean.test.HelloWorld arg1 arg2
  • jar包运行: java -jar jar包目录\jar包名称.jar 参数1 参数2

    • 例子:java -jar E:\jar\util.jar arg1 arg2

关键字

  • 访问控制
private    protected    public
  • 类,方法和变量
abstract    class    extends    final    implements    interface    native    new
static    strictfp    synchronized    transient    volatile
  • 程序控制
break    continue    return    do    while    if    else    for    
instanceof  switch case    default
  • 异常处理
try    catch    throw    throws
  • 包相关
import    package
  • 基本类型
boolean    byte    char    double    float    int    long    short    null   
true    false
  • 变量引用
super    this    void
  • 保留字
goto    const
  • 不常用字段解释
    • strictfp:在接口和类上加上该标识,会对float和double进行严格计算
    • transient:在对象成员变量中加上该标识,在对象序列化时,被标识变量不会被序列化
    • volatile:在变量前加入该标示,解决多线程情况下变量的可见性和有序性,但无法解决原子性问题,应用场景为,变量的值不参与修改的情况。参见:Java并发编程:volatile关键字解析

this

作用:

  • 解决了局部变量隐藏成员变量的问题

static关键字

  1. 特点:
    1.1 随着类的加载而加载
    1.2 优先于对象存在
    1.3 被类的所有对象共享
    1.4 既可以通过类名调用,也可以通过对象名调用
  2. 内存图
    静态的内容在方法去的静态区
  3. 注意事项
    3.1 静态方法中没有this对象
    3.2 静态只能访问静态

final关键字

(1)是最终的意思,可以修饰类,方法,变量。
(2)特点:
    A:它修饰的类,不能被继承。
    B:它修饰的方法,不能被重写。
    C:它修饰的变量,是一个常量。
(3)面试相关:
    A:局部变量
        a:基本类型 值不能发生改变
        b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的
    B:初始化时机
        a:只能初始化一次。
        b:常见的给值
            定义的时候。(推荐)
            或者静态代码块中。
            构造方法中。

注意事项:

类名前
    不使用:
        privateprotectedstatic
    使用:
        权限修饰符:默认修饰符,public
        状态修饰符:final
        抽象修饰符:abstract
 成员变量
     不使用:
        abstract
     使用 
        权限修饰符:private,默认的,protectedpublic
        状态修饰符:staticfinal

数据类型

  • 基本数据类型

    A:整数            占用字节数
        byte            1
        short           2
        int             4
        long            8
    B:浮点数
        float           4
        double          8
    C:字符
        char            2
    D:布尔
        boolean         1
    
    注意:!!!!!
        整数默认是int类型,浮点数默认是double。
    
        长整数要加L或者l。
        单精度的浮点数要加F或者f。
    

思考题和面试题

  • 下面两种方式有区别吗?

        float f1 = 12.345f;     // 本身是一个float类型
        float f2 = (float)12.345;   // 开始是一个double类型,强转为float类型
    
  • 下面的程序有问题吗,如果有,在哪里呢?

        byte b1 = 3;
        byte b2 = 4;
        byte b3 = b1 + b2;  // 有问题,byte参与运算就转换为int类型,编译会报错
        byte b4 = 3 + 4;    // 常量,先把结果计算出来,然后看是否在byte的范围内,如果在,就不报错
    
  • 下面的操作结果是什么呢?

        byte b = 130;   // 编译报错,130不在范围内
        byte b = (byte)130;     // -126 源码反码补码!???
    
  • 字符参与运算

        是查找ASCII里面的值
        'a'     97
        'A'     65
        '0'     48
    
        System.out.println('a');    // a
        System.out.println('a' + 1);    // 98
    
  • 字符串参与运算

        这里其实是字符串的连接
    
        System.out.println("hello"+'a'+1);  // helloa1
        System.out.println('a'+1+"hello");  // 98hello
        System.out.println("5+5="+5+5);     // 5+5=55
        System.out.println(5+5+"=5+5");     // 10=5+5
    

赋值运算符

扩展的赋值运算符的特点
隐含了自动强制转换。

面试题:
short s = 1;
s = s + 1;(编译错误)

short s = 1;
s += 1;(<==>s=(short)(s+1))
请问上面的代码哪个有问题?

位运算

后续补充…..


方法

  • 方法重载:方法名称相同,参数列表不同,与返回值无关。
  • 方法覆盖:方法名称相同,参数列表相同,返回值相同。

java内存分配

  • 栈:存储局部变量(在方法定义中或者方法申明上定义的变量)以及常量值

    数据使用完毕就消失

  • 堆:存储所有new出来的对象


    每一个new出来的东西都有地址
    每一个变量都有默认值
    byte,short,int,long 0
    float,double 0.0
    char '\u0000'
    boolean false
    引用类型 null
    数据使用完毕后,在垃圾回收器空闲的时候回收。

  • 方法区:

    class内容区域:文件中的内容,包含成员变量和成员方法,每个class的方法会有一个地址,为堆中的调用提供连接
    静态区:静态变量和静态方法

    这里写图片描述

  • 本地方法去:与本地系统相关
  • 寄存器:CPU相关

创建对象,内存的流程图:
(1)把Student.class文件加载到内存
(2)在栈内存为s开辟空间
(3)在堆内存为学生对象申请空间
(4)给学生的成员变量进行默认初始化。null,0
(5)给学生的成员变量进行显示初始化。林青霞,27
(6)通过构造方法给成员变量进行初始化。刘意,30
(7)对象构造完毕,把地址赋值给s变量
这里写图片描述


成员变量和局部变量区别

  1. 在类中的位置
    成员变量:类中,方法外
    局部变量:在方法中或方法声明上
  2. 在内存中的位置
    成员变量:堆
    局部变量:栈
  3. 初始化的值
    成员变量:有默认值
    局部变量:没有默认值,只有定义,赋值,才能使用
  4. 生命周期
    成员变量:随着对象的创建而创建,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的结束而消失

this

作用:

  • 解决了局部变量隐藏成员变量的问题

构造方法

  • 格式:
    • 方法名和类名相同
    • 没有返回值类型,void也没有
    • 没有返回值
        思考题:构造方法中可不可以有return语句呢?        *****
        可以。而是我们写成这个样子就OK了:return;
        其实,在任何的void类型的方法的最后你都可以写上:return;

代码块执行顺序

看程序写结果:

    A:一个类的静态代码块,构造代码块,构造方法的执行流程
        静态代码块 > 构造代码块 = 显示初始化 (看顺序) > 构造方法
    B:静态的内容是随着类的加载而加载
        静态代码块的内容会优先执行
    C:子类初始化之前先会进行父类的初始化   
注: 类成员变量的初始化顺序:显式初始化与构造代码块的初始化等级一致,故由代码顺序决定初始化顺序,但注意的是构造代码块不能加数据类型


结果是:
    静态代码块Fu
    静态代码块Zi
    构造代码块Fu
    构造方法Fu
    构造代码块Zi
    构造方法Zi
class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}

class ExtendsTest2 {
    public static void main(String[] args) {
        Zi z = new Zi();
    }
}

方法重写和方法重载的区别

  • 方法重写:方法名,参数和返回值都相同
  • 方法重载:方法名相同,参数不同,与返回值无关

继承

继承的好处

A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类产生了一个关系,是多态的前提

继承的弊端

A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
    原则:低耦合,高内聚。
    耦合:类与类的关系
    内聚:自己完成某件事情的能力
B:打破了封装性

继承的成员关系

A:成员变量
    a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单
    b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢?
        子类的方法访问变量的查找顺序:
            在子类方法的局部范围找,有就使用。
            在子类的成员范围找,有就使用。
            在父类的成员范围找,有就使用。
            找不到,就报错。
B:构造方法
    a:子类的构造方法默认会去访问父类的无参构造方法
        是为了子类访问父类数据的初始化
    b:父类中如果没有无参构造方法,怎么办?
        子类通过super去明确调用带参构造
        子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
        让父类提供无参构造

    注意事项:
this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。

多态

多态中的成员访问特点

    A:成员变量
        编译看左边,运行看左边
    B:构造方法
        子类的构造都会默认访问父类构造
    C:成员方法
        编译看左边,运行看右边
    D:静态方法
        编译看左边,运行看左边
        (静态和类相关,算不上重写,所以,访问还是左边的)

多态继承中的内存图解

这里写图片描述

多态中的对象变化内存图解

这里写图片描述

面试题

class A {
    public void show() {
        show2();
    }
    public void show2() {
        System.out.println("我");
    }
}
class B extends A {
    /*
    public void show() {
        show2();
    }
    */

    public void show2() {
        System.out.println("爱");
    }
}
class C extends B {
    public void show() {
        super.show();
    }
    public void show2() {
        System.out.println("你");
    }
}
public class DuoTaiTest4 {
    public static void main(String[] args) {
        A a = new B();
        a.show();// 爱

        B b = new C();
        b.show();// 你
    }
}

抽象类

抽象类的特点

    A:抽象类和抽象方法必须用关键字abstract修饰
    B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
    C:抽象类不能实例化
    D:抽象类的子类
        a:是一个抽象类。
        b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。

抽象类的问题

    A:抽象类有构造方法,不能实例化,那么构造方法有什么用?
        用于子类访问父类数据的初始化
    B:一个类如果没有抽象方法,却定义为了抽象类,有什么用?    
        为了不让创建对象
    C:abstract不能和哪些关键字共存
        a:final    冲突
        b:private 冲突
        c:static 无意义

接口

接口的成员特点

    A:成员变量
        只能是常量
        默认修饰符:public static final
    B:构造方法
        没有构造方法
    C:成员方法
        只能是抽象的
        默认修饰符:public abstract

类与类,类与接口,接口与接口

    A:类与类
        继承关系,只能单继承,可以多层继承
    B:类与接口
        实现关系,可以单实现,也可以多实现。
        还可以在继承一个类的同时,实现多个接口
    C:接口与接口
        继承关系,可以单继承,也可以多继承

内部类

内部类访问规则

A:可以直接访问外部类的成员,包括私有
B:外部类要想访问内部类成员,必须创建对象

成员内部类

  • 成员内部类不是静态的:
    外部类名.内部类名 对象名 = new 外部类名.new 内部类名();
  • 成员内部类是静态的:
    外部类名.内部类名 对象名 = new 外部类名.内部类名();
30,20,10

        class Outer {
            public int num = 10;

            class Inner {
                public int num = 20;

                public viod show() {
                    int num  = 30;

                    System.out.println(num);
                    System.out.println(this.num);
                    System.out.println(Outer.this.num);
                }
            }
        }

局部内部类

A:局部内部类访问局部变量必须加final修饰。
B:为什么呢?
    因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。
    所以,堆内存还是用该变量,而该变量已经没有了。
    为了让该值还存在,就加final修饰。
C:匿名内部类是局部内部类的简化心事
D:匿名内部类的面试题(补齐代码)
        interface Inter {
            void show();
        }

        class Outer {
            //补齐代码
            public static Inter method() {
                return new Inter() {
                    public void show() {
                        System.out.println("HelloWorld");
                    }    
                };
            }
        }

        class OuterDemo {
            public static void main(String[] args) {
                Outer.method().show(); //"HelloWorld"
            }
        }

复制

浅复制:

将基本数据类型的值进行复制和引用类型的地址进行复制

深复制:

将基本类型的值和引用类型的值进行复制

字符串

面试题1:

    String s = new String("hello");和String s = "hello"的区别?
    前者有两个地址值,一个是在方法区的常量的地址值,另一个是new String()的地址值,有两个对象
    后者是直接赋值,到方法区去找他的地址只有一个对象

面试题2:

    String s1 = "hello";
    String s2 = "world";
    String s3 = "helloworld";
    System.out.println(s3 == s1 + s2);// false  s1+s2会在堆中新建一个地址,地址值不相同(+会重新new一个对象)
    System.out.println(s3.equals((s1 + s2)));// true

    System.out.println(s3 == "hello" + "world");// false 这个我们错了,应该是true
    System.out.println(s3.equals("hello" + "world"));// true

面试题3:

String,StringBuffer,StringBuilder的区别
String: 内容是不可变的
StringBuffer: 是一个容器,内容是可变的,同步的,线程安全,效率低
StringBuilder: 也是一个容器,内容是可变的,不同步的,线程不安全,效率高

面试题4:

StringBuffer是如何实现线程安全的:
除构造方法外和部分insert和indexOf方法外,都使用了在方法上加同步锁的方式保证线程安全,而未加锁的insert和indexOf方法是通过调用父类,父类再调用其本身的已加锁的方法保证线程安全。


Integer

面试题1:

-128到127之间的数据缓冲池问题
但特殊和要注意的是: 若传入的是 -128~127 的值,则不是引用类型,而是类似
于基本类型的常量池中的值,故而可以用 == 号去判断
即: new Integer(127)==new Integer(127);    //true

简单算法

冒泡排序

public static void bubbleSort(int[] arr){
    for(int i=arr.length-1;i>0;i--){
        for(int j=0;j<i;j++){
            if(arr[j]>arr[j+1]){
                int temp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
}

选择排序

public static void selectSort(int[] arr){
    for(int i = 0;i<arr.length-1;i++){
        for(int j = i + 1;j<arr.length;j++){
            if(arr[j]<arr[i]){
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
        }
    }
}

二分查找(需要先排序)

    public static int binarySearch(int[] arr,int value){
        int start = 0;
        int end = arr.length-1;
        while(end>=start){
            int mid = (end-start)/2+start;
            if(arr[mid]<value){
                start = mid+1;
            }else if(arr[mid]>value){
                end = mid-1;
            }else{
                return mid;
            }
        }
        return -1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值