Java --1

本文详细介绍了Java语言的基础知识,包括数据类型、运算符、控制结构、数组、类与对象的概念以及内存分配。深入探讨了类变量、构造器、单例模式、内部类和枚举的用法。同时,讲解了注解和方法重载等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

课程  --》 【韩顺平 Java】 https://www.bilibili.com/video/BV1fh411y7R8/?p=8&share_source=copy_web&vd_source=8977f681475280eda810fba7f418ae06

一、基础

1)编程思想

Java概述

  • 历史

  • 特点

  • Java运行机制

  • JDK

    

  • 转义字符

  • Java开发规范

【.java文件中的每一个class编译后,都会对应生成一个.class文件】

  • JavaAPI
  • 注释
    • 单行        //
    • 多行        /*    */
    • 文档        /**    */

变量

  • 数据类型
  • 变量基本使用
  • 数据类型转换

运算符

  • 运算符介绍
  • 算术
  • 关系
  • 逻辑
  • 赋值
  • 三元
  • 优先级
  • 二进制
  • 位运算符

控制结构

  • 顺序
  • 分支(if else switch)
  • 循环(for,while,do while)
  • break
  • continue
  • return

数组,排序,查找

  • 一维数组

 下标从0开始编号

数组介绍
数组注意细节
值传递和引用传递
//在仅声明但是没有分配内存空间情况下调用数组会空指针报错

//------------------------------1.动态初始化----------------------
//先声明数组
//数据类型[] 数组名;
//数据类型 数组名[];
int a [];

//再分配空间
//数组名 = new 数据类型[];
a = new int[];

//声明数组并分配内存空间
//数据类型[] 数组名 = new 数据类型[大小];
//数据类型 数组名[] = new 数据类型[大小];
int[] b = new int[];


//创建数组,名字为a,能存放5个int
int[] a = new int[5]





//-------------------------------2.静态初始化------------------------
//double类型的数组,名字是sum
doubel[] sum = {1,2,3,4,5,6,7};



//--------------------------------3.数组赋值机制------------------------------

//基本数据类型,复制赋值
int n1 = 10;
int n2 = n1;
n2 = 80;      //结果:n1 = 10, n2 = 80

//数组,内存地址赋值
int[] a = {1,3,5,7,8,9};
int[] b = a;
b[0] = 10;    //结果:a[0] = 10, b[0] = 10



//------------------------------4.数组操作-------------------------
//访问数组
int i = sum[5] //i=6;

//数组长度:数组名.length
sum.length;

//遍历数组
for(int i = 0; i < sum.length; i++){
    sout(sum[i]);
}

//数组拷贝
int[] a1 = {1,3,5,7,8,9};
int[] a2 = new int[a1.length];
for(int i = 0; i < sum.length; i++){
    a2[i] = a1[i];
}

//数组反转
int[] a1 = {11,22,33,44,55,66};
int temp = 0;
int len = a1.length;
for(int i = 0; i < len/2; i++){
    temp = a1[len-1-i];
    a1[len-1-i] = a1[i];
    a1[i] = temp;
}

  • 二维数组
数据类型[][] 变量名 = new 数据类型[][]
数据类型[] 变量名[]  = new 数据类型[][]
数据类型 变量名[][]  = new 数据类型[][]

int[][] arr = {{1,2,3},
               {0,0,0},
               {3,2,1}}


//杨辉三角形
    public static void main(String[] args) {
        int[][] arr = new int[10][];
        for(int i = 0; i<arr.length; i++){
            arr[i] = new int[i+1];
            for (int j = 0; j<arr[i].length;j++){
                if(j == 0 || j == arr[i].length-1){
                    arr[i][j] = 1;
                }else{
                    arr[i][j] = arr[i-1][j]+ arr[i-1][j-1];
                }
            }

        }
        for(int i = 0; i<arr.length; i++){
            for(int j = 0; j<arr[i].length; j++){
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }

二维数组内存形式

  • 排序
排序介绍
冒泡排序介绍

//冒泡排序基础
        int[] arr = {88,87,51,12,47,13,56};
        int temp = 0;
        for(int j = 0; j<arr.length-1;j++){
            for (int i = 0; i < arr.length-j-1;i++){
                temp = arr[i+1];
                if(arr[i]>arr[i+1]){
                    arr[i+1] = arr[i];
                    arr[i] = temp;
                }
            }
        }
        for(int n =0;n<arr.length;n++){
            System.out.println(arr[n]+"\t");
        }




  • 顺序查找

思路:输入一个内容,遍历数组并逐个匹配内容

  • 二分查找

思路:在有序列表中,判断输入的值和中间的值哪个比较大,将数组数据分成两部分

面向对象

  • 类与对象
类与对象的内存分配机制
对象内存分布1
对象内存分布2        
创建对象流程
class Person{
    
} 

public static void main(String[]args){
    Person p; //声明对象cat
    p = new Person(); //创建对象
}
  • 克隆对象
//思路
public class Main {
    public static void main(String[] args) {
        A a = new A();
        a.age = 15;
        a.name = "aabb";
        a.price = 150;
        A a2 = a.copy(a);
        System.out.println(a2.age);
    }
}

class A {
    int age ;
    String name ;
    int price;

    public A copy(A a){
        A a2 = new A();
        a2.age = a.age +15 ;
        a2.name = a.name;
        a2.price = a.price;
        return a2;
    }
}
  • 成员方法
方法调用机制

//定义方法
public 返回数据类型 方法名(形参列表){
    方法体语句;
    return 返回值;
}

//void表示没有返回值
public void ...
  • 成员方法传参机制
    • 基本数据类型:传递值
    • 引用类型:传递内存地址
    • 方法内创建的对象,若没有return此对象,则在方法结束后会被堆内存回收
  • 递归
基本数据类型 - 递归调用内存图解

 参数传入引用类型变量时,因为传入的是同一个内存地址,就会共享引用类型的数据

递归规则

//---------------------打印问题----------------------
public class Main {
    public static void main(String[] args) {
        A a = new A();
        a.re(4);
    }
}

class A {
    public void re(int n){
        if (n>2){
            re(n-1);
        }
        System.out.println(n);
    }
}


//重复调用同一个方法,因此会先执行递归到最后的方法下方的语句
//即:
public void re(int n){
   if (n>2){
       public void re(int n){
            if (n>2){
                re(...);
            }
//re(4)内被调用,即执行新增的方法re(3),优先于re(4)执行
            System.out.println(n);    
        };
   }
//re(4)最后执行
   System.out.println(n);  
}





//---------------------阶乘问题----------------------
public class Main {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(a.mu(4));
    }
}
class A {
    public int mu(int n){
        if(n==1){
            return 1;
        }else {
            return mu(n-1) * n;
        }
    }
}

 汉诺塔

public class Main {
    public static void main(String[] args) {
        D d = new D();
        d.move(10,'1','2','3');
        System.out.println(d.i);

    }
}
class D {
    int i = 0;
    public void move(int n , char a, char b, char c){
        if(n==1){
            System.out.println(a+"-->"+c);
            i++;
        }else {
            move(n-1 , a, c, b);
            System.out.println(a+"-->"+c);
            move(n-1, b, a, c);
            i++;
        }
    }
}
  • overload
    • 方法重载的介绍和好处
  • 可变参数
    • 可变参数基本概念
    • public int sum (int ... nums){
          int res = 0;
          for(int i ; i< nums.length 'i++){
              res += nums[i];
          }
          return res;
      }
    • 可变参数细节
      //可变参数要放在形参的最后,不允许有多个可变参数
      public void fun(String str,int ... nums){
          
      }
  • 作用域
    • 作用域介绍
    • 作用域细节
    • 作用域注意事项
  • 构造器
    • 构造器介绍
    • 构造器理解
    • 构造器细节
    • 构造器细节
    • public class construction01{
          public static void main (String[]args){
              Person p1 = new Person ("jack",18);
              Person p2 = new Person ("jack");
          }
      }
      
      class Person {
          String name = "";
          int age = 0;
      
          public Person(Sting pname , int page){
              name = pname;
              age = page;
          }
      
          public Person(Sting pname){
              name = pname;
          }
      }
      
  • 创建对象流程分析
    • class Person{
          int age  = 40;
          String name;
          public Person(String n ,int a ){
              name = n;
              age  = a;
          }
      }    
      
      public class const{
          public ststic void main (String [] args){
              Person p1 = new Person("jack",20)
          } 
      }
      
      /*    
          Person p1 = new Person("jack",20)
      
          1.方法区加载person类
          2.堆内存开劈空间保存对象,初始化属性,再属性赋值:age = 40;
          3.构造器开始初始化,常量池开辟空间ox0011,保存"jack"; name赋值ox0011地址,age赋值20
          4.对象赋值给p1
      */
      

  • this

    • this使用细节
    • //在构造器中访问另一个构造器
      
      class T {
          //构造器中使用this
          public T(){
              //注意:访问构造器语法:this(参数列表); 必须放在方法体的第一条
              this("jack",20);    
              
          }
          
          public T(String name , int age){
              
          }
      }
    • 包的作用和语法
    • 包的理解
    • 包的命名规范
    • 常用的包

    • 如何引入包
    • 注意细节

  • 访问修饰符

    • 四种修饰符
    • 访问范围
  • 封装

    • 封装介绍
  • 继承
  • 多态
  • super
  • overwrite
    • 子类重写父类方法
  • Object类详解
  • 断点调试

小项目

2)编程能力

面向对象高级

  • 类变量和类方法

    • 静态变量可以解决的问题
    • 类变量:类中的对象共享
    • 类变量简介
    • 类方法简介
  • 理解main方法语法
    • public static void main(String[] args) {
              for (int i = 0; i < args.length; i++) {
              System.out.println(i+ args[i]);
      }

  • 代码块

    • 代码块简介
    • 代码块理解
    • 代码块的调用顺序优先于构造器

      • 代码块注意事项1,静态代码块

    • 代码块注意事项2,静态代码块
    • 多个静态代码块或静态属性,方法;则按照定义的顺序调用
    • 代码块注意事项3,静态代码块
  • 单例设计模式

    • 单例模式介绍
    • //饿汉式:一般使用单例模式的对象都是重量级对象 
      //对象还没使用,但是类加载的时候对象已经创建好了
      //若后续也没有使用,则造成资源浪费
      
      public class Cat {
          public static void main(String[] args) {
              Dog dog = Dog.getInstance();
      
          }
      }
      
      class Dog{
          private String name;
          private static Dog dog =  new Dog("旺财");
      
          /*
          * 如果保障只能创建一个对象
          * 1.构造器私有化
          * 2.在类的内部直接创建static对象,static属性
          * 3.提供一个static方法,返回对象
          * */
          private Dog(String name){
              this.name = name;
          }
      
          public static Dog getInstance(){
              return dog;
          }
      }
      
    • //饿汉式:一般使用单例模式的对象都是重量级对象 
      //对象还没使用,但是类加载的时候对象已经创建好了
      //若后续也没有使用,则造成资源浪费
      
      //懒汉式:使用到该对象时,判断对象是否已创建,未创建再去创建
      
      public class Cat {
          public static void main(String[] args) {
              Dog dog = Dog.getInstance();
      
          }
      }
      
      class Dog{
          private String name;
          private static Dog dog ;
      
          /*
          * 如果保障只能创建一个对象
          * 1.构造器私有化
          * 2.在类的内部直接创建static对象,static属性
          * 3.提供一个static方法,返回对象
          * */
          private Dog(String name){
              this.name = name;
          }
      
          public static Dog getInstance(){
              if(dog == null){
                  dog = new Dog("旺财");
              }
              return dog;
          }
      }
      
    • 单例设计饿汉式,懒汉式区别
  • final关键字
    • 调用被final static一起修饰的变量,不会导致类的加载
    • //被final static一起修饰的变量,不会导致类的加载
      class AA {
          public final static int i = 100 ;
          static{
              System.out.print("静态代码块");
          }
      }
      
      public class Main{
          public static void main (String[] args){
              System.out.print(AA.i);
          }
      }
      
      

  • 抽象类

    • 抽象类介绍
    • 抽象类细节1
    • 抽象类可以有已实现方法 

    • 抽象类细节2
    • 抽象方法不可被 private , final,static修饰,这三个关键字与重写相违背

  • 接口

  • 内部类
    • 局部内部类(有类名,定义在方法或代码块中)
    • 匿名内部类(没有类名)
      • 只是用一次的对象,可以使用匿名内部类
      • 
        
        class Outer{//外部类
            private int outer_i = 0;
            private void pri_m(){}
            public void mether(){
                //------------------------基于接口的匿名内部类----------------------------
                //需求:
                //1.想使用接口AA,并创建对象
                //2.传统方式:写一个类,实现接口,创建对象
                Animal people = new People();
                Animal cat = new Cat();
                people.eat();
                cat.eat();
        
                //但是需求是IA、IA2类只是用一次,往后再不使用,则浪费资源
                //因此可以使用匿名内部类来简化开发
                //animal的编译类型:Animal
                //animal的运行类型:匿名内部类,类名由系统分配 -Outer$1
                /*
                    底层:
                    Animal animal =  new Animal(){...};
                           -- 相当于 --
                        class Outer$1 implements Animal{
                        @Override
                        public void eat() {
                            System.out.println("匿名内部类重写eat方法");
                        }
                    };
                 */
        
                //jdk底层在创建匿名内部类Outer$1,立刻就创建了Outer$1实例,并把地址返回给animal
                //匿名内部类只能生成一个实例,实例可以多次调用
                Animal animal =  new Animal(){
        
                    @Override
                    public void eat() {
                        System.out.println("匿名内部类重写aa方法");
                    }
                };
                animal.eat();
                //----------------------------------------------------------------
        
        
                //----------------------------基于类的匿名内部类------------------------
                /*
                    分析:
                        1.father的编译类型 Father
                        2.father的运行类型 Outer$2
                    底层:
                        Father father = new Father("jack"){...};
                           -- 相当于 --
                        class Outer$2 extend Animal{...}
                    同时"jack"会传递给Father的构造器
                 */
                Father father = new Father("jack"){
                    @Override
                    public void test() {
                        int i1 = outer_i; //基于类的匿名内部类,可以直接访问外部类的私有变量
                        pri_m(); //基于类的匿名内部类,可以直接访问外部类的私有方法
                        System.out.println("匿名内部类重写了Father.test()");
                    }
                };
                father.test();
        
                //----------------------------------------------------------------
        
        
                //----------------------------基于抽象类的匿名内部类------------------------
                Plant plant = new Plant() {
        
                    @Override
                    public void grow() {
                        System.out.println("重写父类Plant的grow()");
                    }
                };
                plant.grow();
        
        
            }
        }
        
        interface Animal {
            public void eat();
        }
        
        class People implements Animal {
            @Override
            public void eat() {
                System.out.println("People实现接口,重写aa()方法");
            }
        }
        
        class Cat implements Animal {
            @Override
            public void eat() {
                System.out.println("Cat实现接口,重写aa()方法");
            }
        }
        
        
        
        class Father{
            private int i = 100;
            public Father(String name) {
            }
            public void test(){
            }
        }
        
        abstract  class Plant{
            public abstract void grow();
        }
        
        
        public class note {
            public static void main(String[] args) {
                Outer outer = new Outer();
                outer.mether();
        
            }
        }
        
        
        
        class Outer{//外部类
            private int outer_i = 0;
            private void pri_m(){}
            public void mether(){
                Animal animal =  new Animal(){
                    int i1 = outer_i; //基于接口的匿名内部类,可以直接访问外部类的私有变量
                    //pri_m(); //基于接口的匿名内部类,因为接口中没有定义该方法,不可以直接访问外部类的私有方法
                    @Override
                    public void eat() {
                        System.out.println("匿名内部类重写aa方法");
                    }
                };
                animal.eat();
        
                Father father = new Father("jack"){
                    @Override
                    public void test() {
                        int i1 = outer_i; //基于类的匿名内部类,可以直接访问外部类的私有变量
                        pri_m(); //基于类的匿名内部类,可以直接访问外部类的私有方法
                        System.out.println("匿名内部类重写了Father.test()");
                    }
                };
                father.test();
        
                Plant plant = new Plant() {
                    int i1 = outer_i; //基于抽象类的匿名内部类,可以直接访问外部类的私有变量
                    //pri_m(); //基于抽象类的匿名内部类,因为抽象类中没有定义该方法,不可以直接访问外部类的私有方法
                    @Override
                    public void grow() {
                        System.out.println("重写父类Plant的grow()");
                    }
                };
                plant.grow();
            }
        }
        
        interface Animal {
            public void eat();
        }
        
        class People implements Animal {
            @Override
            public void eat() {
                System.out.println("People实现接口,重写aa()方法");
            }
        }
        
        class Cat implements Animal {
            @Override
            public void eat() {
                System.out.println("Cat实现接口,重写aa()方法");
            }
        }
        
        
        
        class Father{
            private int i = 100;
            public Father(String name) {
            }
            public void test(){
            }
        }
        
        abstract  class Plant{
            public abstract void grow();
        }
        
        
        public class note {
            public static void main(String[] args) {
                Outer outer = new Outer();
                outer.mether();
        
            }
        }
      • 匿名内部类的应用
        //匿名内部类的应用
        /*
            传统方法实现接口是创建一个类实现接口,但是该类只调用一次则会浪费资源
        */
        interface Inter_a {
            void show();
        }
        
        public class Note2 {
            public static void main(String[] args) {
        
                f1(new Inter_a() {
                    @Override
                    public void show() {
                        System.out.println("把匿名内部类直接当参数写入");
                    }
                });
            }
        
            public static  void f1(Inter_a ia ){
                ia.show();
            }
        }

    • 成员内部类(没有static)
      • 
        class Outerr{
            private int i = 100;
            public void f1(){
                System.out.println("Outer的f1()");
            }
            class Innerr{
                public void f1(){
                    //成员内部类调用外部类的方法可以使用:Outerr.this.f1();
                    Outerr.this.f1();
                    System.out.println("Innerr的f1方法");
                }
        
                public Innerr getInnerrInstance(){
                    return new Innerr();
                }
            }
        }
        
        
        public class Note2 {
            public static void main(String[] args) {
                Outerr outer = new Outerr();
        
                //外部其他类,使用成员内部类的三种方式
                //第一种 outer.new Innerr();相当于把 new Innerr() 当做是Outerr的成员
                //属于一种语法
                Outerr.Innerr inner = outer.new Innerr();
                System.out.println(inner.getClass()); // class Outerr$Innerr
        
                //第二种 在外部类中,编写一个方法,可以返回Innerr的对象
                Outerr.Innerr gii =  inner.getInnerrInstance();
        
                //成员内部类方法与外部类重名,则就近原则
                inner.f1();
        
            }
        }
        

    • 静态内部类(有static)
      • 
        class Outerr{
            private int i = 100;
            private static String name = "ten";
        
            public static void f1(){
                System.out.println("outer.f1()");
            }
            public  void f2(){
                System.out.println("inner.f2()");
            }
        
        
            //使用static修饰的内部类,即是静态内部类
            static class Innerr2{
                 //静态内部类Innerr可以直接访问外部类Outerr的static属性
                //但是无法访问外部类的非静态成员属性
                String n = name;
        
                //内部类与外部类的方法重名,则就近原则
                public static void f1(){
                    System.out.println("inner.f1()");
                }
                public static void f2(){
                    System.out.println("inner.f2()");
                }
            }
            //被private修饰的内部类,其作用域只在Outerr范围内
            private static class Innerr{
                public static void f1(){
                    System.out.println("inner.f1()");
                }
                public static void f2(){
                    System.out.println("inner.f2()");
                }
            }
        }
        
        
        public class Note2 {
            public static void main(String[] args) {
                //可以直接访问静态内部类的方法, 无需创建对象再调用
                Outerr.Innerr2.f1();
            }
        }
        

枚举和注解

  • 自定义类实现枚举
    • public class enum02 {
          public static void main(String[] args) {
      
          }
      }
      
      //自定义枚举类
      //季节固定只有四个,若增加其他东西,或把名字更改了,则会破坏类的设计思路
      class Season2{
          //对枚举对象,属性使用final修饰,实现低层优化
          //枚举对象使用大写,常量的命名规范
          private String name;
          private String desc;
      
          static final Season SPRING = new Season("sp","warm");
          static final Season SUMMER = new Season("su","hot");
          static final Season AUTUMN = new Season("au","cool");
          static final Season WINTER = new Season("wi","cold");
      
          private  Season2(String name, String desc) {
              this.name = name;
              this.desc = desc;
          }
      
          //不提供setXXX方法
          public String getName() {
              return name;
          }
          public String getDesc() {
              return desc;
          }
      
      }

  • enum关键字实现枚举
    • enum Season2{
          /**
              1.使用了enum替代class
              2.static Season SPRING = new Season("sp","warm");
                  直接写作
              SPRING("sp","warm")
              3.如果有多个变量,使用,隔开
              4.如果使用enum实现枚举,要求将定义常量的对象,写在前面
           SPRING("sp","warm"),SUMMER("su","hot"),AUTUMN("au","cool");
           */
      
          SPRING("sp","warm"),
          SUMMER("su","hot"),
          AUTUMN("au","cool"),
          //使用无参构造器也可以直接定义
          WINTER;
      
      
          private String name;
          private String desc;
          private Season2(){
          }
          private  Season2(String name, String desc) {
              this.name = name;
              this.desc = desc;
          }
      
          public String getName() {
              return name;
          }
          public String getDesc() {
              return desc;
          }
      
          @Override
          public String toString() {
              return "Season2{" +
                      "name='" + name + '\'' +
                      ", desc='" + desc + '\'' +
                      '}';
          }
      }
      
      public class enum02 {
          public static void main(String[] args) {
              //枚举类的方法
              Season2 s2 =  Season2.AUTUMN;
              //输出枚举对象的name
              System.out.println(s2.name());
      
              //输出枚举对象的次序,从0开始
              System.out.println(s2.ordinal());
      
              Season2.SPRING.toString();
              Season2.SPRING.name();
      
              //values()返回Season2[] ,含有定义的所有枚举对象
              Season2[] values = Season2.values();
              for (Season2 s:values) {
                  System.out.println(s);
              }
      
              //将字符创转换为已有的枚举常量
              //根据valueOf()的入参,到Season2的枚举对象中查找,如果找到则返回对象,没有则报错
              Season2 ss2 = Season2.valueOf("SPRING");
              System.out.println(ss2);
      
              //比较两个枚举对象是否相同
              System.out.println(s2.compareTo(ss2));
      
      
      
      
          }
      }

  • JDK内置的基本注解类型
    • 注解
    • @override:限定方法是重写父类方法,该注解只能用于方法
      • (语法校验)写了注解,则编译器会去检查是否真的重写了父类方法,如果没有重写,则编译错误
    • @deprecate:表示某个程序元素已过时(类,方法等)版本升级过渡使用
      • 调用变量或者方法时,名字会有中划线
    • @suppresswarnings:抑制编译器警告
    • @Interface:表示一个注解类,不是注解
  • 元注解:对注解进行注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值