Java学习(一)

注:基础语法不做过多学习,从数组开始。

数组

1.数组的创建

int[] x;               //静态创建1
x=new int[]{1,1,1};

int[] y={1,1,1};       //静态创建2


int[] x1=new int[3];   //动态创建
x1[0]=1;

2.数组排序

2.1.选择排序

public void selection(int[] x){
    int[] x=new int[]{5,4,3,7,6,10,8,9,2,1};
    for (int i = 0; i < x.length; i++) {
        int minIndex=i;           //默认最小值索引为第一个元素
        for (int j=i+1;j<x.length;j++){
            if (x[j]<x[minIndex]){           //交换元素值
                int temp;
                temp=x[j];
                x[j]=x[minIndex];
                x[minIndex]=temp;
            }
        }
    }
    System.out.println(Arrays.toString(x));  //打印元素
}

2.2.冒泡排序

public static void Bubble(int[] x){
    for (int i = 0; i < x.length-1; i++) {      //循环次数为数组长度-1,因为最后一次不用作比较(只有一个元素)
        for (int j=0;j<x.length-i-1;j++){     //每次都是从第一个元素开始与后面元素开始比较
            if (x[j]>x[j+1]){                 //交换
                int temp;
                temp=x[j];
                x[j]=x[j+1];
                x[j+1]=temp;
            }
        }
    }
    System.out.println(Arrays.toString(x));
}

2.3*.快速排序*

Arrays.sort(x);

3.fill方法

int[] y=new int[5];
Arrays.fill(y,3);

 int[] z=new int[5];
 Arrays.fill(z,2,4,23);

4.copyOf,copyOfRange和System.arraycopy方法

int[] x={1,2,3,4,5,6};
int[] y=Arrays.copyOf(x,10);    //如果长度超过原数组长度,则用0补

int[] z=Arrays.copyOfRange(x,1,3); //复制范围是[1,3)

int[] a=new int[5];
System.arraycopy(x,1,a,2,2);//参数1 :源数组 参数2:从源数组哪个下标开始复制 
// 参数3:复制到的目标数组 //参数4: 从目标数组的哪个下标位置开始放入 参数5:复制源数组多长

5.数组的equals方法和compare方法

int[] x={1,2,3,4,5,6};
int[] y={1,2,3,4,5,6};
boolean b = Arrays.equals(x, y);//两个数组相同,返回true,否则false
int i = Arrays.compare(x, y);//x>y,返回1,相同0,x<y返回-1

6.二维数组

int[][] x={{1,2},{3,4},{5,6,7},{8},{9,10}};//静态创建二维数组1
int[][] y;                                 //静态创建二维数组2
y=new int[][]{{1,2},{3,4},{5,6,7},{8},{9,10}};

int[][] z=new int[3][];                    //动态创建二维数组,第二维还没有初始化引用时会出现异常
//z[0]={1,2,3};
int[] a=new int[]{1,2,3};
int[] a1=new int[]{2,3};
int[] a2=new int[]{1};
z[0]=a;
z[1]=a1;
z[2]=a2;

1.成员变量与局部变量的区别

java类的成员变量,都有默认值

整数:0

浮点数:0.0

boolean:false

字符:‘\u0000’

引用类型:null

java类的成员变量,在下面所有的方法中,都可以访问到

局部变量,没有默认值

方法体中声明的变量

方法参数中的变量

代码块中的变量

成员变量有默认值,局部变量没有默认值,产生的原因?

JVM进行类加载和字节码执行,这两个阶段时依次执行

JVM(Java虚拟机)通过ClassLoader类加载器进行类加载,过程涉及到"加载"、“准备”、"解析"和初始

化,类的成员变量初始化,是在JVM类加载的阶段完成。

成员变量:静态(static)成员变量、非静态成员变量(初始化阶段赋值,根据代码中的赋值情况,如果没有

赋值,则使用默认值,有赋值,则使用代码中的赋值。当对象实例化后,成员变量会随着对象分配到

java堆内存中)。

局部变量:存储在栈内存中

2.对象创建的原理

程序计数器、Java栈、堆、本地方法栈、方法区

当我们创建一个对象时,同时操作了栈和堆

在栈内存中保存对象的引用

对象的属性保存中堆内存中

操作对象都是通过引用完成,一旦引用出栈,没有被引用的对象就变成了垃圾,应该被回收

编写类文件的时候,类文件存储在硬盘上,还没有被加载到内存中。在主方法中,创建了这个类的对

象,才会被加载到内存中,进行处理。

3.构造器

  1. 也称作构造器,严格来讲,构造方法不是方法

  2. 构造方法要求和类名相同,没有返回值类型,也没有void,可以有return,表示方法的结束,不能返

回值。

  1. 构造方法主要作用是完成对象的初始化工作。

  2. 每个java类,都至少有一个构造方法,如果不写构造方法,编译器会自动提供一个构造方法,没有

任何参数和语句的,默认的空构造方法。如果一旦写了构造方法,编译器不会再提供默认的构造方

法。

  1. 一个类可以定义多个构造方法(构造方法的重载)

  2. 一般情况,都会写一个无参的构造方法,这是一个好的编程习惯

  3. 构造方法的调用:

如果是在其他类中,通过new 的方式来调用构造方法

如果是在自己的类中,可以在构造方法之间进行互相调用。使用this([参数])。必须写在构造方

法中的第一行

8.快捷生成 alt+insert

4.static

4.1.概述

类成员变量或静态成员变量:使用static修饰的,作用范围在整个类的所有对象上。所有对象共享这个变

量,在内存中只有一个副本。访问通过 类名.变量名 访问。在类加载时被初始化,存储在堆里。

实例成员变量:没有static修饰,作用范围在某个实例对象上。在创建对象时被初始化,存在多个副本。

各个对象不互相影响。通过 实例对象名.变量名 访问

类方法或静态方法:使用static修饰,不能直接使用实例变量,只能直接使用静态变量。只能直接调用静

态方法,不能直接调用实例方法。通过 类名.方法名() 访问

不允许使用this关键字

实例方法:没有static修饰,既可以使用静态变量,又可以使用实例变量。既可以直接访问实例方法,又

可以直接访问静态方法。 通过 实例对象名.方法名() 访问

静态代码块>构造代码块>构造方法

静态代码块:类加载的时候执行,并且只执行一次,优先于各种代码块和构造方法,最开始执行的。

构造代码块:在创建对象时被调用,每创建一次对象,都会执行一次构造代码块。 执行顺序,优先于构

造方法执行。一个类如果有多个构造方法时,每通过构造方法,创建一个对象,代码块都会被执行一

次。但是对于构造方法来讲,只执行某一个构造方法(根据参数执行)。

4.2.案例:统计类创建了多少个对象

public class Test2 {
    public static void main(String[] args) {
        K k1=new K(1);
        K k2=new K("abc");
        K k3=new K(1,"abc");
        K k4=new K();
        System.out.println(K.count);
    }
}
class K{
    private int x;
    private String y;
    public static int count;
    {
        count++;              //构造代码块,每创建一个对象调用一次
    }

    public K() {
    }

    public K(int x, String y) {
        this.x = x;
        this.y = y;
    }

    public K(String y) {
        this.y = y;
    }

    public K(int x) {
        this.x = x;
    }
}

4.3.单例模式

设计模式:在某些项目环境下,针对某些问题,提供的一种通用的解决方案。

Gang of Four(GOF):23种软件设计模式

单例模式:保证一个类只能创建一个实例对象,自行实例化,并向整个系统提供这个对象。

实现:

构造方法私有

提供一个当前类的私有静态成员变量

提供一个公有的静态方法,返回成员变量

class Single{                       //单例模式
    private static final Single singleInstance=new Single();
    Single(){}
    public static Single getInstance(){
        return singleInstance;
    }
}
class Single2{                     //懒汉式单例模式
    private static Single singleInstance;
    Single2(){}
    public static Single getInstance(){
        if (singleInstance==null) {
            singleInstance = new Single();
            return singleInstance;
        }
        return singleInstance;
    }
}

单例模式懒汉式和饿汉式的区别

5.访问修饰符

privatedefaultprotectedpublic
同类TTTT
同包FTTT
子类FFTT
通用性FFFT

类的访问修饰符

public :所有类都可以访问

继承

1.子类实例化过程

  1. 父类的构造方法,不能被子继承

  2. 在子类的构造方法中,调用了父类的构造方法

  3. 如果父类有无参的构造方法,子类super()可以省略

  4. 如果父类中没有无参的构造方法,子类super(参数)不可以省略

  5. 如果使用super()显式地调用父类的构造方法,要求必须写在子类构造方法中的第一行

  6. 子类的构造方法中,不能同时出现super()和this()

在子类创建对象时,是否也创建了父类的对象。答:不会创建父类对象。只是创建了父类空间,并进行

了初始化操作。

2.属性的隐藏

在父类中定义一个属性,在子类中定义了一个同名的属性,在子类中访问,会隐藏父类的属性

在子类中,有两个同名属性,一个是继承自父类的,使用super.属性名访问,一个是子类自己的,使用

this.属性名访问

在方法中,如果访问到属性,继承自父类的方法,使用的是父类的属性,子类自己的方法,使用的是子

类属性。

如果父类中有一个静态变量,则被所有子类所共享,其中一个子类修改了值,其他子类访问也是修改后

的值。如果子类自己写了一个同名的静态变量,则子类中访问的是自己的变量,不再是父类变量

3.方法覆盖

java的类只支持单继承,一个类只能有一个直接父类

也叫作方法重写,子类中对父类(祖先类)存在的同名方法,进行改造,去覆盖父类同名方法的机制。

方法重写的要求:

1、方法名必须相同

2、参数列表必须相同

3、访问修饰符 大于等于父类方法的访问修饰符

4、父类方法不能是私有的

5、返回值类型 小于等于父类方法的返回值类型

6、异常处理:

运行时异常:

子类方法,可以自行决定,抛出任何类型的运行时异常,父类的方法不受影响

检查型异常

父类抛出了检查型异常,子类可以不抛出任何异常或者子类可以抛出相同类型异常,或者子类可以抛

出比父类方法异常小的异常类。不能抛出比父类方法异常大的异常,也不能抛出和父类方法不同的其他

类型检查型异常

使用方法重写的场景:子类和父类的方法要完成相同功能,但采用不同的算法或公式。

抽象类存在的意义

4.final

final不可以和abstract放在一起对方法和类进行修饰

final定义常量:

修饰引用类型: 无法更改引用所指向的对象地址。引用的对象属性可以修改。

修饰基本数据类型:值不能被修改

编译期常量、非编译期常量

不是所有的final修饰的字段都是编译期常量,非编译期常量,在被初始化之后无法修改

编译期常量与运行时常量

static final:

一个既是static,又是final的字段,只占据一段不能改变的存储空间。

final定义终结类:

当一个类定义为final 时,就表明不能继承这个类,表示不能产生子类。

final类里面的所有方法,都是隐式的final,不会产生子类,也不会覆盖方法,所以不需要在final类中

为方法加final关键字。

final定义终结方法:

不能被子类重写。所有private方法都是隐式地final方法,在private方法中,不需要使用final关键

字修饰。

final方法可以被重载

final的初始化:

类的普通成员变量,在定义时,可以直接初始化,也可以先不做初始化,在构造方法或构造代码块

中,进行初始化

类的静态成员变量,在定义时,可以直接初始化,也可以先不做初始化,在静态代码块中,进行初

始化

class Test {
    private final int c;{
        c=1;
    }
    
    private static final int x;
    static {
        x=2;
    }

5.多态

5.1.向上转型(上溯造型)

父类的引用指向子类的对象(将子类对象赋值给父类对象)

父类类型 对象名=new 子类类型();

编译时,看左边,运行时,看右边。

只能调用到父类中声明过的方法,不能调用子类中的特殊方法

方法的运行,看子类的结果

属性的调用,看左边

将子类声明成父类类型,得到的对象编译时认为是父类的,运行时认为是子类的,属性是父类的,方法

是子类的。

上溯转型

5.2.向下转型(下溯造型)

子类的引用指向父类的引用

语法: 子类类型 对象名=(子类类型)父类引用;

只能强制转换父类的引用,不能强制转换父类的对象,如果强制转换,编译可以通过,运行时报错误。

转换的前提是父类的引用必须是经过向上转型的对象

可以调用子类中声明的所有方法

5.3.多态

具有多种表现形态,三个必要条件

  1. 要有继承

  2. 要有重写

  3. 父类引用指向子类对象

优点

简化代码

面向抽象编程,不面向具体编程。(依赖倒转原则)

易于扩展 增强代码可读性

5.4.静态方法能否重写

子类可以写一个和父类相同的静态方法,当使用多态机制,将子类声明成父类类型时,调用的静态方

法,还是父类的静态方法,不能实现方法的覆盖。

必须要重写的方法:abstract修饰的抽象方法

不能重写的方法:构造方法、private、final、static

接口

1.JDK8新增方法

default方法(JDK8)

static方法(JDK8)

private方法(JDK9)

public interface Inter1 {
    default void test(){               //默认方法,实现这个接口时,默认继承了这个方法,可以重写也可以不重写
        System.out.println("11111111");
        test2();
    }

    static void test1(){               //静态方法,接口名调用
        System.out.println("2222222222");
    }

    private void test2(){              //接口中默认public,private方法用于接口中的其他方法调用,且只能接口内方法调用
        System.out.println("33333333333");
    }
}

2.内部类

2.1.成员内部类

成员内部类**(普通内部类)**:可以直接访问外部类的变量和方法(包括私有和静态修饰的)。不能

使用static声明变量和方法的。编译后生成的class文件命名为 “外部类名$内部类名”。不能直

接new一个内部类对象,必须使用外部类对象来创建内部类对象

如果外部类和内部类具有相同名称的成员变量或方法,内部类可以直接访问内部类的成员变量

和方法的,如果内部类访问外部类的成员变量或方法时,需要this关键字

public class Test {
    public static void main(String[] args) {
        Outer outer=new Outer();
        Outer.Inner inner=outer.new Inner();
        outer.test();                         //外部类函数
        inner.test();                         //内部类函数
        System.out.println(outer.getX());     //外部类的x
        System.out.println(inner.getX());     //内部类的x
        System.out.println(inner.getY());
    }
}
class Outer{
    public int getX() {
        return x;
    }
    private int x=10;
    public void test(){
        System.out.println("Outer----");
    }
    class Inner{
        public int getY() {
            return y;
        }
        public int getX() {
            return x;
        }
        private int y=9;
        private int x=7;
        public void test(){
            System.out.println("Inner----"+Outer.this.x);//外部类的x
        }
    }
}

2.2.静态内部类

静态内部类:使用static修饰的内部类,不能直接访问外部类的非静态成员变量和方法。如果要

访问外部类的实例变量和方法,需要创建外部类的实例对象。可以创建静态变量和方法。静态

内部类创建对象时,不需要创建外部类的对象,直接可以创建内部类的对象

public class Test1 {
    public static void main(String[] args) {
        Outer1.Inner1 inner1=new Outer1.Inner1();       //可以直接创建内部类对象
        System.out.println(inner1.test());
        System.out.println(inner1.run());
    }
}
class Outer1{
    private static int x=10;
    private int y=9;
    public void test(){

    }
    public static void test1(){

    }
    static class Inner1{
        private int x=1;
        private static int z=5;
        public int test(){
            Outer1.test1();
            return Outer1.x;          //不能访问外部类的非static成员变量y和函数test()
        }
        public int run(){
            Outer1 outer1=new Outer1(); //需要创建外部类的对象才能访问问问罢了的非static方法和变量
            outer1.test();
            return outer1.y;
        }
    }
}

2.3.局部内部类

局部内部类:定义在外部类的方法或代码块中。可以直接访问外部类的所有成员变量和方法(包

括私有的、静态的),不能使用访问修饰符(地位相当于局部变量),可以使用final修饰,防止其

他类去继承。作用范围就在当前的方法或代码块中。

局部内部类访问方法中的变量,jdk1.8之前,必须要求变量是使用final修饰,jdk1.8之后,加入了语法

糖,默认有final修饰,所以在局部内部类方法中,可以访问,但不能修改。

如果局部变量发生了改变,对于匿名内部来讲,是不知道的,所以为了保证数据运行的一致性,使用

final来修饰。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-26ZfOa30-1674821791271)(C:\Users\Peter\AppData\Roaming\Typora\typora-user-images\image-20230113160051706.png)]

class OuterLocal{                    //正确代码
    private int x=10;
    private static void test2(){ }
    public void testn(){ }
    public int  test(){
        int y=10;
        int finalY = y;
        class InnerLocal{
            public void test1(){
                System.out.println(finalY);
            }
        }
        InnerLocal local=new InnerLocal();
        local.test1();
        return ++y;
    }
}

2.4.匿名内部类

匿名内部类:没有名字的一种嵌套类。在实际开发过程中,一个接口/父类的方法在程序员只会

执行一次,如果为了使用它,要创建它的实现类或子类去进行重写。此时,我们可以使用匿名

内部类的方法,减少代码冗余。

语法: new 接口/父类()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Munich*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值