java基础

本文详细介绍了Java的基础知识,包括JDK、JRE、openJDK和不同版本的Java。探讨了Java语言的封装、继承和多态特性,以及程序的跨平台性质。文章深入解析了Java的关键字、重载与重写、多态的实现原理,并讨论了访问权限控制、递归调用、hashCode()与equals()方法的使用。此外,还涵盖了基本类型与包装类型的区别、String类型的存储格式和不可变性,以及内部类、枚举、反射和异常处理等高级主题。
摘要由CSDN通过智能技术生成

javaAPI

命名

J2ME/JavaMe(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE/JavaSE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE/JavaEE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。
Java1.6发布后进行更名:J2ME-JavaMe,J2SE-JavaSE,2EE-JavaEE

jdk 8u191-b12 : jdk 8,update191 ,branch12。
jdk 10.0.2+13 : jdk 10 ,子版本10.0.2 , branch 13。
jdk jdk1.8.0_171 : jdk8,子版本1.8.0, update 171

JDK

Java Development Kit ,java开发工具包,是面向程序员使用java语言编写java程序所需的开发工具包。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm,hotspot debugger等工具软件,还包含了java程序编写所需的文档和demo例子程序。

JRE

Java Runtime Environment,java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境。

openJDK

为开源的Jdk版本,可以下载openJDK源码自己编译成JDK,可以更好的学习hotspot等底层的代码运行情况(通过debug hotspot,native方法等源码)。

java版本

jdk-8u181-linux-arm32-vfp-hflt.tar.gz
jdk-8u181-linux-x64.rpm
jdk-8u181-windows-x64.exe

java特征

java语言的特征

  1. 封装(面向对象,数据抽象)
  2. 继承
  3. 多态

java程序的特征

  1. 跨平台

注意:Java语言是跨平台的,但JVM不是跨平台的


关键字


重载,重写(复写,覆盖)

方法签名:方法名 + 参数列表 来确定唯一方法。

重写(override):

  1. 重写就是子类重写父类的方法
  2. 方法名,参数列表(类型,顺序)和返回值都必须相同
  3. 权限修饰符不能小于被重写方法的修饰符(父类protected,子类> protected)
  4. 方法不能抛出新的异常或者是比被重写方法声明更加宽泛的检查型异常

重载(overload):

  1. 重载就是同一个类中
  2. 多个方法名相同,但参数列表不同(包括参数个数和参数一一对应后参数类型),与返回值权限修饰符异常无关
class Supper{
   
	// 编译报错,参数列表+get方法名相同,为同一个方法没有重载
	// List<Integer>和List<String>同一个类型,泛型擦除
	void get(List<Integer> list){
   
	}
	int get(List<String> list) {
   
		return 1;
	}
}

class Supper{
   
	// 重载
	protected void get(List<Integer> list){
   
	}
	int get(List<Integer> list, Integer i){
   
		return 1;
	}
	int get(Integer i, List<Integer> list){
   
		return 2;
	}
}

多态

多态也叫动态绑定/后期绑定/运行时绑定,对立的概念静态绑定/前期绑定/编译器绑定。基于RTTI(运行时类型识别)实现。
增强了java语言的可拓展性。基于多态的面向接口编程成为java代码设计的重要原则之一。

类中各种抽象元素的绑定类型

类型 绑定类型 解释
static方法 编译期绑定
编译期绑定 任何域访问操作都将由编译器解析,域访问不是多态的
private方法 编译期绑定 private方法也属于final方法
final方法 编译期绑定 final告诉编译器“关闭”动态绑定,不需要对方法进行动态绑定
除static/final/private的方法 运行时绑定 每一个对象实例的“mark word”中都会存放对象的实际类型信息,JVM执行子系统(识别invokevisual等字节码命令)能找到正确的方法并调用
构造函数 编译期绑定 构造器不具多态性(它们实际上时static方法,只不过该static声明时隐式的)

RTTI:

class Shape {
   
	void draw() {
   System.out.println(this + ".draw()");}
	abstract String toString();
}
class Circle extends Shape {
   
	String toString() {
   return "Circle";}
}
class Square extends Shape {
   
	String toString() {
   return "Circle";}
}
public static void main(String[] args){
   
	List<Shape> shapelist = Arrays.asList(new Circle(), new Square());
	for(Shape shape : shapeList){
   
		shape.draw();
	}
}
// output
Circle draw()
Square draw()
public class Supper{
   
	int num = 2;
	String get(){
   
		return "supper";
	}
	// static方法,静态绑定
	static String show(){
   
		return "supper show";
	}
	// final方法,不会被复写,不会进行动态绑定
	final String fgo(){
   
		return "supper go";
	}
}
public class Sun extends Supper{
   
	int num = 3;
	String get(){
   
		return "sun";
	}
	static String show(){
   
		return "sun show";
	}
	//编译报错,父类为final方法,此方法拒绝override重载
	//String go(){
   
		//return "sub go";
	//}

	public static void main(String[] args){
   
		Supper supper = new Sun();
		System.out.println(supper.num);
		System.out.println(supper.get());
		System.out.println(supper.show());
		System.out.println(supper.fgo());
	}
}
## 结果
2
sun
supper show
supper go

进阶:基于字节码和JVM理解多态

虚分派:JVM为了实现多态指定的规则,首先从被调用方法对象的类的实现中查找对应的方法,如果没有找到,则去父类查找,直到找到函数并实现调用。虚分派不管引用类型,只查找引用指向的对象的类型

虚分派在JVM中的实现:vtable(visual table虚表)来实现虚分派的规则。在JMM的方法区中,每一个类都维护一个方法表,该方法表记录每一个方法代码的索引(偏移量)。创建并生成方法表时,JVM会先扫描父类,然后子类,同样的方法(签名相同:名称,参数)会被子类的索引覆盖。

JVM规定在遇到invokevirtual,invokeinterface指令时,就需要遵循虚分派规则,invokestatic指令不遵循虚分派规则,以引用类型代表的类的方法表作为方法代码查找的索引表

上述代码的字节码片段

静态常量池:
#7 = Methodref          #20.#58        // com/study/memery/Supper.get:()Ljava/lang/String;
 #9 = Methodref          #20.#61        // com/study/memery/Supper.show:()Ljava/lang/String;
 #10 = Methodref          #20.#62        // com/study/memery/Supper.fgo:()Ljava/lang/String;

运行时常量池:

supper.get()
12: invokevirtual #7                  // Method get:()Ljava/lang/String;

supper.show()
23: invokestatic  #9                  // Method show:()Ljava/lang/String;

supper.fgo()
33: invokevirtual #10                 // Method fgo:()Ljava/lang/String;

JVM将直接调用,间接调用抽象成4个指令:

指令 解释 是否跟多态有关
invokevirtual 用于方法调用,调用public,protected修饰且不被static,final修饰的方法 有关
invokeinterface 跟invokevirtual差不多,如果父类引用是接口,就用这个;父类引用是类就用invokevirtual 有关
invokespecial 用于调用私用方法、构造函数 无关
invokestatic 用于静态方法调用 无关

访问权限控制

public/private/protected/default
修饰符可以修饰类,构造函数,成员变量,方法

访问权限 含义 本类 本包的类 非本包子类 非本包非子类
public 公共的
protected 保护访问权限
default 包访问权限
private 私有的

访问权限:public > protected > package > private

defualt : 包访问权限、friendly、package


递归调用

  1. 方法进栈与出栈的顺序:先进后出
  2. 方法在出栈的时候,执行的是return语句。因为出栈就意味着方法结束并消费,如果没有return语句,那么方法出栈的时候什么都不执行,就直接销毁。
public class Main {
   
    public static void main(String[] args) {
   
        split(12);
    }
    public static int split(int number) {
   
        if (number > 1) {
   
            if (number % 2 != 0) {
   
            	System.out.print(split((number + 1) / 2));
            }
           	System.out.print(split(number / 2));
        }
        return number;
    }
}

sout 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值