Java重要知识点

JAVA虚拟机:
  执行java字节码的虚拟机进程(java虚拟机知道底层硬件平台的指令长度和其它特性,使得java程序运行在任意平台成为可能)

指令javac与java:
javac:编译 (将java源文件编译成jvm可识别的字节码文件 .class)
java:运行 (启动jvm,加载运行时所需的类库,执行java字节码文件,起点为main函数)

JDK与JRE:
JDK:java开发工具包与运行环境(包含JRE、编译器和其他工具:如JavaDoc、java调试器);
JRE:java运行环境(将要执行java程序的虚拟机,同时包含了执行applet需要的浏览器插件)

变量的作用域与生存期:
作用域:从变量定义的位置开始,到该变量所在的那对大括号结束;
生存期:变量从定义的位置存活,到达它所在的作用域从内存中消失

逻辑运算符
&&和&:前者若左边为false,右边不参与运算;后者无论左边什么结果,右边都运算
|| 和 |:前者若左边为true,右边不参与运算;后者无论左边什么结果,右边都运算
^异或:两边结果不同为true

练习:对两个变量互换,不使用第三方变量:

int a=3(011),b=5(101);
a=a+b;  //a=8
b=a-b;  //b=3
a=a-b;  //a=5a=a^b;  //a=110
b=a^b;  //b=011
a=a^b;  //a=101
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

数据类型:
引用数据类型:数组、类、接口
基本数据类型:级别从低到高:byte,char,short->int->float->long->double;boolean
对应的对象包装类型:Byte,Character , Short , Integer , Float , Long , Double , Boolean
自动装箱:java编译器将基本数据类型转化为对应的对象包装类型;反之为自动拆箱
强制类型转换:把一个高级别的数赋给一个比它级别低的变量

栈和堆:
java分了5片内存:寄存器、本地方法区、方法区、栈、堆
栈:存储局部变量(数据运算完成,所在区域结束,数据被释放)
堆:存储数组和对象(即封装多个数据的实体)
  1.每个实体都有内存首地址值;
  2.堆内存中的变量都有默认初始化值,因为数据类型和值不同;
  3.垃圾回收机制: Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收heap(堆)中无任何引用的对象占据的内存空间。

成员变量与局部变量区别:
成员变量:定义在类中;在类中有效;存在于堆内存中,随着对象创建而存在,消失而消失
局部变量:定义在方法中、参数上、语句中;在自己所属的大括号内有效;存在于栈内存中,随着所属区域运行而存在,结束而释放

成员变量与静态变量区别:
成员变量:属于对象,成为实例变量;存在于堆内存中,随着对象创建而存在,消失而消失;只能被对象调用
静态变量:所属于类,成为类变量;存在于方法区中,随着类的加载而存在,消失而消失;可以被对象和类调用

static关键字: 用来修饰成员变量和成员函数,表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
  1.被静态修饰的数据成为所有对象共享数据(数据共享时定义成静态成员);
  2.被静态修饰的成员可以直接被类名调用;
  3.静态随着类的加载而加载,且优于对象存在
  所以:
  1.静态方法中不能使用this、super关键字,this代表对象,静态可能没有对象;
  2.Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
  3.不可以在static环境中访问非static变量。因为static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

重载与重写(覆盖):**
重载:发生在同一个类中,参数个数、类型不同,与返回值类型无关;
重写:发生在继承中,必须有相同的方法名,参数列表和返回类型

接口和抽象类:
抽象类 : 单继承;可定义非抽象方法供子类直接继承使用;成员修饰符可自定义(private,protected或者是public);使用 is a 关系;
接口:多实现;都是抽象方法需子类实现;成员在接口中都是public;使用 like a 关系;

interface Inter{
    【public static final】int x=3; //成员变量public abstractvoid show();  //成员方法
}
    
    
  • 1
  • 2
  • 3
  • 4

关键字 instanceof :判断对象是否实现了指定接口或继承了指定的类
          <对象 instanceof 类型>
值传递和引用传递:
对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

进程与线程:
进程:正在进行中的程序,负责一个应用程序运行时的内存分配空间;
线程:进程中的一个程序执行控制单元,一个执行序列,负责应用程序的执行顺序。一个进程可以有多个线程。

创建线程的三种方式:
  1.继承Thread类,子类复写run方法 (若一个类已有父类无法使用,单继承局限性);
  2.实现Runnable接口 ;
  3.应用程序可以使用Executor框架来创建线程池;
  其中,实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

线程在的几种状态:
  就绪(Runnable):线程准备运行,不一定立马就能开始执行。
  运行中(Running):进程正在执行线程的代码。
  等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。(只能由notify或notifyAll唤醒)
  睡眠中(Sleeping):线程被强制睡眠。
  I/O阻塞(Blocked on I/O):等待I/O操作完成。
  同步阻塞(Blocked on Synchronization):等待获取锁。
  死亡(Dead):线程完成了执行。

锁:  
  1.同步:同时只有一个线程可以访问共享数据;
   同步方法和同步代码块的区别: 在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁)。

  2.在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?
   监视器和锁在Java虚拟机中一块使用。
   监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。
   每个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码

  3.死锁: 两个进程都在等待对方执行完毕才能继续往下执行,两个进程都陷入了无限的等待中。
   避免死锁:N个线程访问N个资源时,指定获取锁的顺序,并强制线程按照指定的顺序获取锁和释放锁

Java集合类框架:

1.集合和数组区别:
  数组:长度固定;可以存储基本数据类型和引用数据类型;存储的元素必须是同一个数据类型;
  集合;长度可变;只能存储引用数据类型(数组、类、接口);存储的对象可以是不同数据类型;

2.集合类关系:
 Collection:代表一组对象,每一个对象都是它的子元素。
   Set:无序的Collection,不包含重复元素。
     HashSet:底层数据结构是哈希表;线程不同步;无序高效(hashCode值相同时再用equals方法判断,若为true,元素相同,不存)
     TreeSet:底层数据结构是二叉树;线程不同步;有序排列
   List:有序的Collection,可包含重复元素。
     ArrayList : 底层数据结构是数组,线程不同步,查询元素速度快;
     LinkedList :底层数据结构是链表,线程不同步,增删元素速度快;
     Vector : 底层数据结构是数组,线程同步,查询、增删元素速度慢;
 
 Map:可以把键(key)映射到值(value)的对象,键不能重复。
   HashTable:底层数据结构是哈希表;线程同步;不存储null值
   HashMap:底层数据结构是哈希表;线程不同步;可存储null值

补充:Java中的HashMap的工作原理:
  Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)

3.相关问题:
  1).为什么集合类没有实现Cloneable和Serializable接口:
    克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
 
  2). 迭代器 (Iterator) :
     是一个接口,用于取集合中的元素。     
     Iterator接口提供了很多对集合元素进行迭代的方法(hasNext, Next, Remove),迭代器可以在迭代的过程中删除底层集合的元素

  3). Iterator和ListIterator的区别:
    Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
    Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
    ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
 
  4)Enumeration接口和 Iterator接口的区别:
    Enumeration速度是Iterator的2倍,同时占用更少的内存。但是,Iterator远远比Enumeration安全(因为其他线程不能够修改正在被iterator遍历的集合里面的对象)。同时,Iterator允许调用者删除底层集合里面的元素,这对Enumeration来说是不可能的。

Applet和Servlet:

1.applet运行在启用了java的浏览器中。Applet主要用来创建动态交互的web应用程序。

2.applet的生命周期:
Init:每次被载入的时候都会创建applet控制类的实例,然后初始化applet。
Start:开始执行applet。
Stop:结束执行applet。
Destroy:卸载applet之前,做最后的清理工作。

3.Applet是运行在客户端主机的浏览器上的客户端Java程序。而Servlet是运行在web服务器上的服务端的组件。applet可以使用用户界面类,而Servlet没有用户界面,相反,Servlet是等待客户端的HTTP请求,然后为请求产生响应。

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

JAVA虚拟机:
  执行java字节码的虚拟机进程(java虚拟机知道底层硬件平台的指令长度和其它特性,使得java程序运行在任意平台成为可能)

指令javac与java:
javac:编译 (将java源文件编译成jvm可识别的字节码文件 .class)
java:运行 (启动jvm,加载运行时所需的类库,执行java字节码文件,起点为main函数)

JDK与JRE:
JDK:java开发工具包与运行环境(包含JRE、编译器和其他工具:如JavaDoc、java调试器);
JRE:java运行环境(将要执行java程序的虚拟机,同时包含了执行applet需要的浏览器插件)

变量的作用域与生存期:
作用域:从变量定义的位置开始,到该变量所在的那对大括号结束;
生存期:变量从定义的位置存活,到达它所在的作用域从内存中消失

逻辑运算符
&&和&:前者若左边为false,右边不参与运算;后者无论左边什么结果,右边都运算
|| 和 |:前者若左边为true,右边不参与运算;后者无论左边什么结果,右边都运算
^异或:两边结果不同为true

练习:对两个变量互换,不使用第三方变量:

int a=3(011),b=5(101);
a=a+b;  //a=8
b=a-b;  //b=3
a=a-b;  //a=5a=a^b;  //a=110
b=a^b;  //b=011
a=a^b;  //a=101
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

数据类型:
引用数据类型:数组、类、接口
基本数据类型:级别从低到高:byte,char,short->int->float->long->double;boolean
对应的对象包装类型:Byte,Character , Short , Integer , Float , Long , Double , Boolean
自动装箱:java编译器将基本数据类型转化为对应的对象包装类型;反之为自动拆箱
强制类型转换:把一个高级别的数赋给一个比它级别低的变量

栈和堆:
java分了5片内存:寄存器、本地方法区、方法区、栈、堆
栈:存储局部变量(数据运算完成,所在区域结束,数据被释放)
堆:存储数组和对象(即封装多个数据的实体)
  1.每个实体都有内存首地址值;
  2.堆内存中的变量都有默认初始化值,因为数据类型和值不同;
  3.垃圾回收机制: Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收heap(堆)中无任何引用的对象占据的内存空间。

成员变量与局部变量区别:
成员变量:定义在类中;在类中有效;存在于堆内存中,随着对象创建而存在,消失而消失
局部变量:定义在方法中、参数上、语句中;在自己所属的大括号内有效;存在于栈内存中,随着所属区域运行而存在,结束而释放

成员变量与静态变量区别:
成员变量:属于对象,成为实例变量;存在于堆内存中,随着对象创建而存在,消失而消失;只能被对象调用
静态变量:所属于类,成为类变量;存在于方法区中,随着类的加载而存在,消失而消失;可以被对象和类调用

static关键字: 用来修饰成员变量和成员函数,表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
  1.被静态修饰的数据成为所有对象共享数据(数据共享时定义成静态成员);
  2.被静态修饰的成员可以直接被类名调用;
  3.静态随着类的加载而加载,且优于对象存在
  所以:
  1.静态方法中不能使用this、super关键字,this代表对象,静态可能没有对象;
  2.Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
  3.不可以在static环境中访问非static变量。因为static变量在Java中是属于类的,它在所有的实例中的值是一样的。当类被Java虚拟机载入的时候,会对static变量进行初始化。如果你的代码尝试不用实例来访问非static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。

重载与重写(覆盖):**
重载:发生在同一个类中,参数个数、类型不同,与返回值类型无关;
重写:发生在继承中,必须有相同的方法名,参数列表和返回类型

接口和抽象类:
抽象类 : 单继承;可定义非抽象方法供子类直接继承使用;成员修饰符可自定义(private,protected或者是public);使用 is a 关系;
接口:多实现;都是抽象方法需子类实现;成员在接口中都是public;使用 like a 关系;

interface Inter{
    【public static final】int x=3; //成员变量public abstractvoid show();  //成员方法
}
  
  
  • 1
  • 2
  • 3
  • 4

关键字 instanceof :判断对象是否实现了指定接口或继承了指定的类
          <对象 instanceof 类型>
值传递和引用传递:
对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。

进程与线程:
进程:正在进行中的程序,负责一个应用程序运行时的内存分配空间;
线程:进程中的一个程序执行控制单元,一个执行序列,负责应用程序的执行顺序。一个进程可以有多个线程。

创建线程的三种方式:
  1.继承Thread类,子类复写run方法 (若一个类已有父类无法使用,单继承局限性);
  2.实现Runnable接口 ;
  3.应用程序可以使用Executor框架来创建线程池;
  其中,实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

线程在的几种状态:
  就绪(Runnable):线程准备运行,不一定立马就能开始执行。
  运行中(Running):进程正在执行线程的代码。
  等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。(只能由notify或notifyAll唤醒)
  睡眠中(Sleeping):线程被强制睡眠。
  I/O阻塞(Blocked on I/O):等待I/O操作完成。
  同步阻塞(Blocked on Synchronization):等待获取锁。
  死亡(Dead):线程完成了执行。

锁:  
  1.同步:同时只有一个线程可以访问共享数据;
   同步方法和同步代码块的区别: 在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁)。

  2.在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?
   监视器和锁在Java虚拟机中一块使用。
   监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。
   每个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码

  3.死锁: 两个进程都在等待对方执行完毕才能继续往下执行,两个进程都陷入了无限的等待中。
   避免死锁:N个线程访问N个资源时,指定获取锁的顺序,并强制线程按照指定的顺序获取锁和释放锁

Java集合类框架:

1.集合和数组区别:
  数组:长度固定;可以存储基本数据类型和引用数据类型;存储的元素必须是同一个数据类型;
  集合;长度可变;只能存储引用数据类型(数组、类、接口);存储的对象可以是不同数据类型;

2.集合类关系:
 Collection:代表一组对象,每一个对象都是它的子元素。
   Set:无序的Collection,不包含重复元素。
     HashSet:底层数据结构是哈希表;线程不同步;无序高效(hashCode值相同时再用equals方法判断,若为true,元素相同,不存)
     TreeSet:底层数据结构是二叉树;线程不同步;有序排列
   List:有序的Collection,可包含重复元素。
     ArrayList : 底层数据结构是数组,线程不同步,查询元素速度快;
     LinkedList :底层数据结构是链表,线程不同步,增删元素速度快;
     Vector : 底层数据结构是数组,线程同步,查询、增删元素速度慢;
 
 Map:可以把键(key)映射到值(value)的对象,键不能重复。
   HashTable:底层数据结构是哈希表;线程同步;不存储null值
   HashMap:底层数据结构是哈希表;线程不同步;可存储null值

补充:Java中的HashMap的工作原理:
  Java中的HashMap是以键值对(key-value)的形式存储元素的。HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合添加和检索元素。当调用put()方法的时候,HashMap会计算key的hash值,然后把键值对存储在集合中合适的索引上。如果key已经存在了,value会被更新成新值。HashMap的一些重要的特性是它的容量(capacity),负载因子(load factor)和扩容极限(threshold resizing)

3.相关问题:
  1).为什么集合类没有实现Cloneable和Serializable接口:
    克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
 
  2). 迭代器 (Iterator) :
     是一个接口,用于取集合中的元素。     
     Iterator接口提供了很多对集合元素进行迭代的方法(hasNext, Next, Remove),迭代器可以在迭代的过程中删除底层集合的元素

  3). Iterator和ListIterator的区别:
    Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
    Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
    ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
 
  4)Enumeration接口和 Iterator接口的区别:
    Enumeration速度是Iterator的2倍,同时占用更少的内存。但是,Iterator远远比Enumeration安全(因为其他线程不能够修改正在被iterator遍历的集合里面的对象)。同时,Iterator允许调用者删除底层集合里面的元素,这对Enumeration来说是不可能的。

Applet和Servlet:

1.applet运行在启用了java的浏览器中。Applet主要用来创建动态交互的web应用程序。

2.applet的生命周期:
Init:每次被载入的时候都会创建applet控制类的实例,然后初始化applet。
Start:开始执行applet。
Stop:结束执行applet。
Destroy:卸载applet之前,做最后的清理工作。

3.Applet是运行在客户端主机的浏览器上的客户端Java程序。而Servlet是运行在web服务器上的服务端的组件。applet可以使用用户界面类,而Servlet没有用户界面,相反,Servlet是等待客户端的HTTP请求,然后为请求产生响应。

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

猜你喜欢

转载自blog.csdn.net/weixin_41897234/article/details/80615595