java基础知识

JDK:编写java程序的程序员使用的软件

JRE:运行java程序的用户使用的软件,包含虚拟机,不包含编译器。为不需要编译器的用户提供的。

 

1. 三种字符串

  String:字符串常量

  StringBuffer:字符串变量(线程安全)

  StringBuilder:字符串变量(非线程安全)

  三种字符串的操作效率:StringBuilder > StringBuffer > String

  (1) String:字符串常量

  

  

  操作String相当于重新new一个对象,还可能涉及到垃圾回收,因此最慢

  (2) StringBuffer和StringBuilder

    a. 二者都是继承AbstractStringBuilder

    b. 对二者的变量进行操作就是直接对该对象进行更改,而不进行new和回收的操作,所以速度比String快很多。

    c. 二者主要区别在于StringBuffer是线程安全的,StringBuilder是非线程安全的。StringBuffer大部分方法都是被synchronized关键字修饰,为了保证多线程同步,一些线程可能遇到阻塞的情况,这就使得Stringbuffer的运行时间增加,故StringBuffer效率略低于StringBuilder。

  (3) 使用总结

    String:适用于少量的字符串操作的情况

    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

    StringBuffer:适用于多线程下在字符缓冲区进行大量操作的情况

  (4) 字符串常量的拼接(快)

    

  (5) 字符串+字符串变量、字符串变量之间的拼接(慢)

    

  (6) 使用以数组为底层数据结构的类型时,最好要预估大小

    例如:StringBuilder底层数据结构就是一个字符数组value[],该数组默认大小为16,当超出这个大小时,会重新分配内存进行扩容(原大小的2倍+2),然后将原来数组的内容拷贝到新的数组,原数组被丢弃,这个过程非常消耗资源,要尽量避免这种操作。

 

2. synchronized关键字

  synchronized是java中的关键字,是一种同步锁。它修饰的对象有以下几种:

  (1) 修饰一个代码块:被修饰的代码块称为同步语句块,其作用范围是大括号{}括起来的代码,作用对象是调用这个代码块的对象。

  (2) 修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象

  (3) 修饰一个静态方法:其作用的范围是整个静态方法,作用的对象是这个类的所有对象

  (4) 修饰一个类:其作用范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象

 

  a. 无论synchronized关键字加在方法上还是对象上,如果他作用的对象是非静态的,则取得的锁是对象;如果synchronized作用的对象是一个静态方法或者一个类,则它取得的锁是类,该类所有的对象同一把锁。

  b. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码

  c. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

 

3. 传参

  (1) 基本数据类型

  举例:int num = 10;   

  

  (2) 引用类型

  举例:String str = "Hello";

  

  (3) 什么是传值?

    参数的值的拷贝

  (4) 什么是传引用?

    参数的地址

    对于引用类型的变量,要清楚三个概念:

    a. 变量的值

    b. 变量的地址

    c. 变量所引用的对象的地址

  (5) java是传值还是传引用?

    java只有传值,没有传引用,参数传递本质上就是复制的过程

  (6) 基本数据类型的赋值

    举例:int num = 10;

      

      int num1 = num;

      

      num1 = 20;

      

  (7) 基本数据类型的传参

    

  方法不能改变基本数据类型的参数

  (8) 引用类型的赋值

    举例:A a1 = new A();

       A a2 = a1;

      

  (9) 引用类型的传参

    

  方法可以修改外部对象(实参)的属性,方法不能让外部对象引用一个新对象

  (10) 引用类型的赋值之String

    举例:String str = "Hello";

       String str1 = str;

       str1 = "World";

       

  (11) 引用类型的传参之String

    

  String是不可变类型,没有提供改变value[]值的方法

 

4. 继承

  子类可以继承父类的哪些属性和方法

    (1) public/protected修饰的

    (2) 同一个包内,friendly修饰的

  子类无法继承父类的哪些属性和方法

    (1) 构造方法

    (2) private修饰的

    (3) 不同包内friendly修饰的

  构造函数可以被继承吗?

    (1) 不会被继承,只会被调用

    (2) 创建有参构造函数后,系统就不再有无参构造函数,如果没有任何构造函数,系统会默认有一个无参构造函数

    (3) 构造函数第一句一定是调用父类的构造函数,如果不显式调用父类有参构造函数,系统会默认调用父类的无参构造函数super();如果父类没有无参构造函数,又没有显式的调用有参构造函数-->报错。

 

5. 多态

  父类引用指向子类对象

    (1) 若子类重写了某方法,则父类引用调用子类重新定义的新方法

    (2) 若子类未重写某方法,则父类引用调用父类本身的旧方法

    (3) 若子类隐藏了父类的成员变量,则父类引用会访问到父类被隐藏的成员变量

    (4) 若子类未隐藏父类的成员变量,则父类引用调用父类本身的成员变量

    (5) 父类引用不能访问子类新定义的方法(如果想访问,需要强制类型转换)

  子类引用指向自身对象

    (1) 若子类重写了某方法,则子类引用调用子类重写的新方法

    (2) 若子类未重写某方法,则子类引用调用父类本身的旧方法

    (3) 若子类隐藏了父类的成员变量,则子类引用调用子类重新定义的新成员变量

    (4) 若子类未隐藏父类成员变量,则子类引用调用父类本身的旧成员变量

    (5) 子类引用可以访问子类新定义的方法

  多态的必要条件

    (1) 继承

    (2) 重写

    (3) 父类引用指向子类对象

  使用父类引用指向子类对象时,该引用只能访问父类的方法和变量,如果子类重写了父类的方法,则会动态调用子类中的方法。(子类无法重写父类中的变量,只能使父类中的变量被隐藏)

  不会重写成员变量,而是隐藏成员变量

    (1) 在一个类中,子类中的成员变量如果和父类中的成员变量同名,那么即使他们类型不一样,父类中的成员变量都会被隐藏。

    (2) 在子类中,父类的成员变量不能被简单的用引用来访问,而是,必须从父类的引用获得父类被隐藏的成员变量。

  访问被隐藏的成员变量:使用父类的引用即可访问(强制类型转化)

 

6. 抽象类和接口

  

  (1) 抽象类描述的是对象整体,包括属性和行为;接口一般描述某些行为

  (2) 抽象类适合用来定义某个领域的固有属性,也就是本质,接口适合用来定义某个领域的扩展功能

  (3) 如果需要多继承,只能用接口

  (4) 如果有一些公用的方法实现,而且这些公用方法随时可能改变,则使用抽象类

  (5) 当注重代码的扩展性和维护性时,应当优先采用接口。接口与实现它的类之间可以不存在任何层级关系,接口可以实现毫不相关类的相同行为,比抽象类的使用更加的方便灵活;接口只关心对象之间的交互的方法,而不关心对象所对应的具体类。接口是程序之间的一个协议,比抽象类的使用更安全、清晰。一般使用接口的情况更多。

 

7. final关键字

  基本用法:

  (1) 修饰类:当用final修饰一个类时,表明这个类不能被继承

  (2) 修饰方法:使用final方法的原因有两个

    a. 把方法锁定,以防任何继承类修改它的含义(父类的final方法不能被子类覆盖,不能被重写,可以重载多个final修饰的方法)

    b. 效率。

  (3) 修饰变量:对于一个final变量,如果是基本数据类型的变量,则其数据一旦在初始化之后便不能修改,如果是引用类型的变量,则在对其初始化之后便不能再让其指向另外一个对象。

    final修饰一个成员变量(属性),必须要显示初始化,有两种初始化方式:一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有构造函数中对这个变量赋初值。

  public class FinalTest{

    private final int i = 0;

    private Object obj;

 

    public FinalTest(){

      i = 1;    //错误

      final Object obj2 = new Object();

      obj2 = new Object();  //错误

    }

  }

 

  被final修饰的引用变量指向的对象内容可变吗?

  答:引用虽然不能再指向其他对象,但是它指向的对象的内容是可变的

 

8. static关键字

  static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。

  方便在没有创建对象的情况下进行调用(方法/变量)

  static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。

  (1) static方法:

    静态方法不依赖于任何对象就可以进行访问;静态方法中不能访问非静态成员方法和非静态成员变量,但是非静态成员方法中可以访问静态成员方法/变量。

  (2) static变量

    静态变量与非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  (3) static代码块

    只会在加载的时候执行一次

  

    

    

 

 

    

 

 

 

    

 

      

    

 

 

      

 

      

    

 

 

 

  

 

    

 

    

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

posted @ 2019-03-16 13:00  欣欣向荣666  阅读(170)  评论(0编辑  收藏  举报