0基础-入门Java SE(第一次接触必看)

本文详细介绍了JavaSE(Java Standard Edition)的基础知识,包括类与接口、方法调用、面向对象编程等核心概念。重点讲解了对象、类、接口、抽象类、内部类、继承、多态以及反射机制,为初学者提供全面的入门指导。
摘要由CSDN通过智能技术生成

目录

 JAVA SE 是什么? 入门级讲解。

JAVA SE(Java Standard Edition,Java 标准版)

顶级理解

版本平台

JAVA SE 基础

一、类和接口

对象 对象

类 类

终态声明

静态声明

权限声明

接口 接口

抽象声明 

接口和抽象类的区别

更新声明

包 套餐 

导入 导入 

二、方法调用

参数传递

Lambda表达式

三、面向对象

封装

普通内部类

局部内部类

匿名内部类

静态内部类

继承

类的继承

接口继承

多态

继承多态

方法多态

反射机制

反射机制运用


 JAVA SE 是什么? 入门级讲解。

JAVA SE(Java Standard Edition,Java 标准版)

        java se是Java技术的核心和基础,是Java ME和Java EE编程的基础 。
Java SE是由Sun 公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的Hot Java浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。这些魅力带来很多便捷和优点,从此呢,Java就逐渐被你们这些可爱的人类广泛的接受了,常用的浏览器均支持Java applet(这个是Java编程的一个小的应用程序,用来提高web页面的交互能力和动态执行能力)。

顶级理解

        Java se 是用来做电脑上能够运行的软件的一个Java平台。是运行Java程序不可缺少的环境。

版本平台

        标准版的Java平台是一个Java2的平台,为用户提供一个程序开发环境。这个程序开发环境提供了开发与运行Java软件的编译器等开发工具、软件库及Java虚拟机。它也是Java2平台、企业版本和Java网页服务的基础。
Java2平台有3个版本,JavaME ,Java SE,Java EE。
其中Java EE 是用来做网站网页的。 Java ME是用来做手机软件app啥的。

JAVA SE 基础

一、类和接口


对象 对象

        java 是面向对象的语言:对象包含了状态和行为,用户通过调用对象的方法、改变对象的属性来实现 java 程序的功能。

Car myCar = new Car("BMW");                          // 创建对象       
me.brand = "Benz";                                   // 修改对象变量                   
me.go("London");                                     // 调用对象方法

        在 java 程序中我们通过类和接口来定义对象的性质:每个 java 文件都是一个定义好的 public 类 / 接口,且类名 / 接口名与文件名相同。

java 文件可以含有多个类 / 接口,但只能有一个 public 类 / 接口供外部访问。


类 类

对象的类型:定义对象含有的变量和方法。

public class Car {     
    // 变量
    String brand;
    String description = "this is a car";
    // static 变量 
    static int number_of_car;  
    // 构造方法
    public car(String brand){        
        this.brand = brand;
    } 
    // 方法  
    public void go(String loc){
        System.out.print("go to" + loc);
    }   
    // static 方法
    void static showNum(){            
        System.out.print(number_of_car);
    }
    // 初始化块
    {       
        number_of_car;                                      
    }
    // static 初始化块
    static{                                                              
        number_of_car = 0;
    }
    // 内部类
    public class Warranty{
        public void repair(){
            System.out.print("repair");
        }    
    }
}
  • 变量

对象中存储的数据。

  • 方法

调用时执行的代码。

  • 初始化块

创建对象前自动执行的代码。

  • 内部类

定义在类中的类。

  • 构造方法

在创建对象时自动执行,不返回任何参数(先执行初始化块,再执行构造方法)。

未定义任何构造方法时,系统会自动添加无参构造方法。

终态声明

  • final 常量: 只能赋值一次,不可更改。
  • 最终类: 不可被继承。
  • final 方法:(弃用)不可被继承。现在所有的 private 方法都隐式地指定为 final。

对于 final 常量,如果编译时就可以确定值,编译器会在编译时直接把这个变量替换成它的值。

静态声明

  • static 变量:该变量由该类的所有对象共享,不需要创建对象也可使用。
  • static 方法:允许直接访问,不需要创建对象也可被调用。如 main 方法。
  • static 初始化块:在创建类的第一个对象前自动执行(先执行静态初始化块,再执行初始化块)。
  • static 内部类:外部类对象共享,只能访问外部类的静态成员。

权限声明

  • public: 允许所有访问。
  • protected: 只允许本类、同包和子类访问。
  • [default]: 允许本类和同包访问。
  • private: 只允许本类访问。

接口 接口

类的规范:只规定应含有哪些方法,而不负责具体实现。

public interface Move{  
    // abstract 方法                   
    public void go(String loc);
    // default 方法                                 
    default void stop() {      
        System.out.print("stop");
    };                  
}
  1. 声明接口:必须且默认为 static final,通常为 public 。
  2. 只允许声明静态常量:必须且默认为 public static final 。
  3. 声明抽象方法:必须且默认为 abstract ,可以为 static。

JDK 1.8 以前,接口中抽象方法必须且默认为 public,不允许实现任何方法。JDK 1.8 以后,接口中抽象方法可以且默认为 default,且允许实现 static 和 default 方法。JDK 1.9 以后,接口中抽象方法可以是 private。*

抽象声明 

  • abstract 方法:只有声明,而没有方法的具体实现。
  • abstract 类:类的模板,不能实例化对象。必须由其他类继承才能使用。
public abstract class Vehicle {
    // 声明变量
    String brand;
    // 声明并实现方法
    public void go(String loc){
        System.out.print("go to" + loc);
    }   
}

接口和抽象类的区别

  1. 接口不能实现普通方法,抽象类可以实现具体的方法、也可以不实现。
  2. 接口只能定义静态常量,抽象类可以定义非静态变量。
  3. 一个实体类可以实现多个接口,但只能继承一个抽象类。

更新声明

  • default 方法:更新接口时添加的新方法,允许旧类实现接口而不实现该方法。

    • 可以直接在接口内实现,供没有定义的旧类直接使用。若类中实现了该方法则覆盖。

    • 如果类实现了多个接口且拥有同名 default 方法:

      1. 两个接口若存在继承关系,调用时优先使用子类方法。
      2. 否则,必须重写子类 default 方法,通过 super 关键字明确实现哪个接口:
class Plane implements Move, Fly{
    ...
    void go(){
        Fly.super.go();                 // 实现选定 default 方法
    }
}

包 套餐 

命名空间,表示 java 文件的存储路径。其路径记录在每个 java 文件首。

package com.company.project.module;                    // 声明存储路径

导入 导入 

在 java 文件中,如果要调用其他 java 文件中定义的类 / 接口,就需要进行导入:

  • 同一存储路径(包)下的 java 文件不需要导入,可以直接调用。

  • 已默认导入 java.lang 路径下所有 java 文件,包含 System、String、Object、Math 等常用类。

  • 如果没有导入对应 java 文件,或者导入了多个同名 java 文件,在调用类 / 接口时需要标明路径。

package com.company.project.module;  

import java.util.Scanner;                             // 导入 java 文件,但不包括内部 static 变量和方法
import java.net.*;                                    // 导入路径下所有 java 文件,但不包括下属文件夹
import static java.lang.Math.PI;                      // 导入 java 文件中的 static 变量或方法

public class Test{
    public void main(String[] args){
        java.io.InputStream in = new java.io.InputStream(System.in);    // 未导入类,调用时需要标明路径
        Scanner sc = new Scanner(in);                                   // 已导入类,可直接调用
        Integer n = sc.nextInt();                                       // 默认导入类,可直接调用
        sc.close();           
    }
}

二、方法调用


参数传递

值传递:在 Java 方法中传递参数,形参本质是实参的副本。

  1. 参数是基础数据类型:对形参的改变不会影响实参。

  2. 参数是指向对象的引用(包括数组、字符串):对对象数据进行更改会影响实参,但改变引用指向的对象不会影响实参。

public class Test{
    public static void main(){
        int i = 0;
        int[] arr = {0};
        test(i, arr);
        System.out.print(i);            // 输出为 0
        System.out.print(arr[0]);       // 输出为 1
    }

    public void test(int i, int[] arr){
        i++;                            // 实参不改变
        arr[0]++;                       // 实参指向的对象改变
        arr = new int[]{2};             // 实参不改变
        return;
    }
}

Lambda表达式

JDK 1.8 新增。


三、面向对象


什么是面向对象

  • 面向过程:根据解决问题的过程,直接设计系统。如 C 语言。

  • 面向对象:将问题分解成多个对象,设计模块化、低耦合的系统。如 java 语言。

    • 特性:封装、继承、多态。

    • 优点:使系统更加灵活,易维护、易复用、易扩展。


封装

普通内部类

        定义在类中的类,可以使用外部类所有属性和方法。普通内部类属于具体对象,因此不能声明 static 成员变量和方法。

        成员内部类依附外部类而存在。也就是说,如果要创建普通内部类的对象,就必须首先存在外部类的对象。

public class Test {
    public static void main(String[] args)  {
        // 创建内部类
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  
        inner.output();
    }
}

// 外部类 
class Outter {
    private int num = "10";
    // 内部类  
    class Inner {
        void output(){
            System.out.println(num);
        }
    }
}

局部内部类

        定义在一个方法或者一个作用域里的内部类。对局部内部类的访问仅限于方法内或者该作用域内,且局部内部类不能被访问权限所修饰。

public class Test {
    public static void main(String[] args)  {
        // 创建内部类
        Factory f = new Factory();
        Gun myrifle = f.getRifle();  
    }
}

class Factory {
    // 局部内部类
    public Gun getRifle(){
        class Rifle extends Gun {   
            int len = 60;
        }
        return new Rifle();
    }
}

匿名内部类

        匿名内部类不用定义名称,但必须继承一个父类或实现一个接口。由于没有类名,匿名内部类不能定义构造器。在创建匿名内部类的时候会立即创建它的实例。因此匿名内部类只能使用一次,通常用来简化代码编写。

        最常用的情况就是在多线程的实现上,创建线程类传入参数需要继承 Thread 类或实现 Runnable 接口。

// 父类或接口
interface Person {
    public void eat();
}

public class Demo {
    public static void main(String[] args) {
        Person p = new Person() { 
            // 定义匿名内部类并直接使用
            public void eat() {
                System.out.println("eat apple");
            }
        };
        p.eat();
    }
}

JDK 1.8 中引入了 Lambda 表达式,你甚至连方法名都不需要写。

public class Demo {
    public static void main(String[] args) {
        Person p = new Person(() -> {
            System.out.println("eat apple");
        });
        p.eat();
    }
}

        局部内部类和匿名内部类都定义在方法中,如果调用方法中的其他局部变量,只能调用外部类的局部 final 变量。因为在多线程中,外部类方法中定义的变量 A 在方法执行完毕后生命周期就结束了,而此时 Thread 对象的生命周期很可能还没有结束。内部类方法中访问的变量 A 实际上是拷贝。这就必须限定变量为 final,否则改动将导致数据不一致。

public class Test {
    public void test(final int b) {
        final int a = 10;
        new Thread(){
            public void run() {
                System.out.println(a);
                System.out.println(b);
            };
        }.start();
    }
}

静态内部类

        静态内部类是不需要依赖于外部类,可以在不创建外部类对象的情况下创建内部类的对象。静态内部类不能使用外部类的非 static 成员变量或者方法。

public class Test {
    public static void main(String[] args)  {
        // 无需外部对象,直接创建内部类
        Outter.Inner inner = new Outter.Inner();
    }
}

class Outter {
    static class Inner {
        int data = 0;
    }
}

继承

类的继承

        子类继承父类后,无需定义也可使用父类定义好的 public/protected 方法和属性。也可以进行扩展和方法的重写。

  • 父类的属性值不会被子类继承,但子类可以通过父类提供的方法得到父类的属性值。
  • 父类的 static 方法不会被子类继承,子类的 static 方法会隐藏父类的同名 static 方法。
  • 父类的构造方法不会被子类继承,子类必须在构造方法首行调用父类构造方法(先构造父类,再构造子类)
  • final public class Trunk extends Car{ 
        // 重定义属性(未公开无法继承)
        String brand;
        String description = "this is a trunk";
        // 扩展属性
        int goods;
        // 扩展方法              
        public void load(int num){
            this.goods += num;
        }
        // 子类构造方法
        public Trunk(String brand){    
            super(brand);        
            this.goods = 0;                          
        }
        // 重写方法
        @Override         
        public void go(String loc){
            super.go(loc);                            
            System.out.print(" with" + goods + "goods"); 
            this.goods = 0;
        }
    }
    

    Object 类是一切 java 类的父类。对于普通的 java 类,即便不声明也默认继承了 Object 类。


接口继承

和类的继承类似。但 Java 类只能单继承,而 Java 接口可以多继承。

interface Charge extends Move, Fight{  
    public abstract void kill(int num);
}

多态

继承多态

  • 重载(overload):定义多种同名方法,调用时根据传入参数判定调用哪种方法。
  • 重写(override):子类定义完全相同的方法覆盖父类。

重写是多态的前提,其允许父类引用指向子类对象(引用类型为父类,指向的实际对象类型为子类)。

Car mycar = new Trunk("Benz");

但不允许子类引用指向父类对象。

Trunk mycar = new Car("Benz");

        如果两个类之间存在继承关系,可以进行强制类型转换。强制类型转换只能改变引用类型,实际指向对象类型不会发生变化。

Trunk newCar = (Trunk)mycar;

方法多态

  • 调用普通方法

    子类同名方法会覆盖父类。执行方法根据实际对象类型来判定,即执行子类重写的方法。

  • 调用 static / private / final 以及构造方法

    特殊方法不能被覆盖,不存在多态。执行方法会根据引用类型来判定,即执行父类方法。

  • 调用成员变量

    父类属性值不会被子类继承,不存在多态。调用变量会根据引用类型来判定,即得到父类属性值。

Car myCar = new Trunk("Benz");

myCar.go("London");                    // (trunk) go to London with 0 goods
myCar.showNum();                       // (car) 1
System.out.print(myCar.description);   // (car) this is a car

Trunk newCar = (Trunk)mycar;           // 强制类型转换
System.out.print(newCar.description);  // (trunk) this is a trunk

反射机制

JAVA 是动态编译语言(运行时才确定类型),支持反射机制。在运行状态中

  • 对于任意一个类,都能够知道这个类的所有属性和方法;
  • 对于任意一个对象,都能够调用它的任意一个方法和属性。

        通过反射机制能更好地支持多态,降低模块耦合,提高代码灵活度(根据传入类名不同,就能实例化出不同的对象)。

        但是在性能上会有较大的损耗。

        尽管在应用层面很少使用反射机制,但在设计基础框架的时候反射机制非常有用。

反射机制运用

        类的相关信息保存在以下类中,通过特定方法获取其对象能够知道这个类的信息。

  • 类 类:类
  • 构造函数 类:类的构造方法
  • 字段 类:类的属性
  • 方法 类:类的方法
public class Reflection {
    public static void main(String[] args) {

        /************************** 获取 Class 对象 **************************/

        // 第一种方式 返回对象的类 【已有对象,获取类无意义】
        Student stu = new Student();
        Class stuClass = stu.getClass();

        // 第二种方式 获取数据类型的静态 class 属性 【需要导入类包】
        Class stuClass = Student.class;

        // 第三种方式 返回路径下的类 【常用】
        Class stuClass = Class.forName("Reflection.Student");

        /************************** 获取 Class 信息 **************************/

        // 获取类名
        String name = stuClass.getName());   

        // 获取类的公有构造方法
        Constructor[] conArray = stuClass.getConstructors();
        // 获取类的全部构造方法
        Constructor[] conArray = stuClass.getDeclaredConstructors();
        // 获取类的指定构造方法(参数)
        Constructor con = stuClass.getConstructor(null);
        Constructor con = stuClass.getDeclaredConstructor(char.class);

        // 获取类的公有属性
        Field[] fieldArray = stuClass.getFields(); 
        // 获取类的全部属性
        Field[] fieldArray = stuClass.getDeclaredFields();
        // 获取类的指定属性(属性名)
        Field f = stuClass.getField("name");    

        // 获取类的公有方法
        Method[] methodArray = stuClass.getMethods(); 
        // 获取类的全部方法                
        Method[] methodArray = stuClass.getDeclaredMethods();
        // 获取类的指定方法(方法名+形参类型)                  
        Method m = stuClass.getMethod("main", String.class);   

        /************************** 在对象中使用 **************************/

        Object obj = con.newInstance();   // 调用公有无参构造方法创建对象
        f.set(obj, "X-man");              // 为对象的公有属性赋值
        m.invoke(obj, "X-man");           // 调用对象的公有方法

    }

        在编译时检查类型安全,编译过后泛型被擦除、实际类型才确定。反射是在编译期模拟 java 运行时的环境读取和调用程序,因此不能获得泛型的实际类型。但可以通过反射越过泛型检查:

        在 String 泛型的集合中,你甚至可以添加一个 Integer 类型的值。

public class Demo {
    public static void main(String[] args) throws Exception{
        ArrayList<String> strList = new ArrayList<>();    
        Class listClass = strList.getClass(); 
        Method m = listClass.getMethod("add", Object.class);
        m.invoke(strList, 100);
    }
}

欲知后事如何、请听下回分解🧐

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二两清酒.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值