努力到达

'Tequila

Life is too short to be ordinary.

Java基础总结(一)

正在准备春招,总结一些Java基础复习一下,通过一些小问题引出知识点,查缺补漏,欢迎大家指正,更新中……


 

关于JVM

Java虚拟机(JVM)是运行Java字节码的虚拟机。JVM有针对不同系统的特定实现(跨平台),“一次编译,到处运行”。(另详细写一篇)

 

JDK与JRE

JDK是Java Development Kit,Java程序开发工具包,面向Java程序的开发者。拥有JRE所拥有的一切,还有编译器和工具,能够创建和编译程序。

JRE是Java运行时环境,面向Java程序的使用者。它是运行已经编译的Java程序所需的所有内容的集合,包括Java虚拟机(JVM),Java类库,Java命令和其他一些基础构建。但是不能创建新程序。

只需运行Java程序,安装JRE即可。如果需要进行Java编程方面的工作,就需要安装JDK。但是在使用JSP部署Web应用程序时,应用程序服务器会将JSP转换为Java servlet,需要使用JDK来编译servlet。

 

Java面向对象

面向对象和面向过程的区别

 

面向过程 :面向过程的性能比面向对象高。因为类调用时需要实例化,开销较大,比较消耗资源,所以当性能是重要考量因素时,比如单片机、嵌入式开发、Linux/Unix等一般面向过程开发。但是面向过程没有面向对象易维护、易复用、易扩展。

 

面向对象:面向对象易维护、易复用、易扩展。因为面向对象有封装、继承、多态三大特性,所以可以设计出低耦合的系统,使系统更加灵活,更易于维护。但是面向对象的性能比面向过程低。

(耦合:模块之间存在依赖,导致改动可能会互相影响,关系越紧密,耦合越强,模块独立性越差)

 

构造器Constructor是否可以被override

Constructor不能被override(重写),但是可以overload(重载),所以可以看到一个类中有多个构造函数的情况。

构造器也可以叫做构造方法。构造器不能被继承。

 

在Java中定义一个不执行任何代码且无参的构造方法的作用

Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中的无参构造方法。因此,如果在父类中只定义了有参构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,这时会发生编译错误。解决办法就是在父类里加上一个不执行任何代码且无参的构造方法。

 

一个类的构造器的作用是什么?若一个类没有声明构造器,该程序能正确执行吗?为什么?

构造器的主要作用是完成对类对象的初始化工作。

可以执行,因为即使一个类没有声明构造器(构造方法),也会有默认的无参构造器。如果我们自己添加了类的构造器(无论是否有参),Java就不会再默认添加无参构造器了,这时候就不可以直接new一个对象而不传递参数了。所以其实我们一直到在不知不觉中使用构造方法,这也是为什么我们在创建对象的时候后面要加一个括号(因为要调用无参构造器)。如果我们重载了有参的构造方法,记得要把无参的构造方法也写出来,避免踩坑。

 

面向对象的三大特征

 

封装

封装是指把一个对象的属性隐藏在对象内部,不允许外部对象直接访问对象内部属性,如果外界需要访问这个属性,那么就提供公有方法对其访问。

 

继承

继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的属性或功能,也可以使用父类的功能,但是不能选择性继承父类。

 

记住以下几点:

子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。

子类不能继承父类中的构造器。

子类继承父类,创建子类对象的时候,会先默认调用父类的构造器。

子类可以重写父类的方法,对父类进行扩展。

 

多态

多态,顾名思义,表示一个对象具有多种的状态。具体表现为父类的引用指向子类的实例。

多态的特点:

  1. 对象类型和引用类型之间具有继承(类)/实现(接口)的关系;
  2. 对象类型不可变,引用类型可变;
  3. 方法具有多态性,属性不具有多态性;
  4. 引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;
  5. 多态不能调用“只在子类存在但在父类不存在”的方法;
  6. 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。
  7. Java实现多态有三个必要条件:继承、重写、向上转型。

 

继承:在多态中必须存在有继承关系的子类和父类。

重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

 

对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

 

接口和抽象类的区别是什么?

抽象类:

  • 抽象类必须使用abstract修饰,子类必须实现抽象类中的抽象方法,如果没有实现的话,那么子类也必须定义成抽象类。
  • 抽象类的默认的权限修饰符为public,可以定义为public或protected,如果定义为private,那么子类无法继承,也就无法实现其抽象方法。同样地,final和abstract不能一起使用。
  • 抽象类是一种引用数据类型。
  • 抽象类不能实例化对象。

 

接口:

  • 接口必须使用interface修饰,接口里的实行默认就是public static final 修饰,接口里的方法默认是public abstract修饰,所以这些可以省略不写。
  • 接口也是一种引用数据类型,接口和接口之间支持多继承。
  • 接口是完全抽象的,是一种特殊的抽象类。
  • 一个类可以实现一个或多个接口。使用implements 关键字修饰,类实现接口了,就要实现接口的所有抽象方法,否则就要将类定义成抽象类。
  • 接口不能实例化对象。

 

接口和抽象类的区别:

  • 一个类只能继承一个抽象类,但是可以实现多个接口。
  • 抽象类中可以有非抽象的方法,而接口里必须都是抽象方法。
  • 接口中的方法不能用static(因为static修饰就不能被重写),抽象类允许static的方法。
  • 接口成员变量默认为public static final,必须赋初值,不能被修改;抽象类中成员变量默认default,可以在子类中被重新定义,也可以被重新赋值。

 

 

方法重载和方法重写:

方法重载:首先方法重载是同一个类中的不同方法间的关系,这些方法具有同名(方法名一样),但是具有不同的参数列表(参数的个数和参数的类型不同)。方法重载其实是同一个类中多态性的表现,调用者可以依据传入不同个数或者不同类型的参数来决定最终调用哪一个同名的方法。方法重载其实是程序编译时的多态性,即代码在编译的时候就决定了使用哪一个方法。

方法重载的原则:

  • 两者的方法名称一致
  • 必须具有不同的参数列表(参数的个数和参数的类型)
  • 可以有不同的参数返回类型
  • 可以有不同的访问修饰符
  • 可以抛出不同的异常

方法重写:方法重写是子类与父类间的关系,子类的方法与父类的方法具有相同的方法名,相同的返回类型,相同的参数列表。方法重写其实是父类与子类间的一种多态性的表现。方法重写其实是代码运行时的多态性,即只有在代码真正运行的时候,才能决定到底使用哪一个真正的方法。

方法重写的原则:

  • 子类不能重写父类中定义为final类型的方法
  • 子类中必须重写父类中定义为abstract的方法
  • 重写方法必须具有相同的参数列表(参数个数和参数类型)
  • 重写方法必须具有相同的返回类型
  • 子类中重写的方法的访问修饰符一定要大于父类中被重写方法的访问修饰符(public>protected>default>private)
  • 子类中重写的方法一定不能抛出新的检查异常或者比父类中被重写的方法申明的更加宽泛的检查型异常,例如:父类中的一个方法抛出了一个IOException的异常,那么其子类中重写的该方法只能抛出IOException异常的子异常,不能抛出IOException的父异常(Exception)
  • 父类中的静态方法不能被重写的,父类中的方法不能被重写为静态方法
  •  构造方法可以重载,不能重写

        

final和static

final关键字一般用在三个地方:变量、方法、类。

1. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

2. 当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。

3. 使用final修饰方法的原因有两个。第一个原因是把方法是锁定,以防任何继承类修改它的含义;第二个原因是效率,在早期的Java实现版本中。会将final方法转为内嵌调用,但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的Java版本已经不需要使用final方法进行这些优化了),类中的所有private方法都隐式地指定为final。

 

static关键字主要有以下四种使用场景:

1. 修饰成员变量和成员方法:被static修饰的成员属于类,不属于单个这个类的某个对象,被类中的所有对象共享,并且建议通过类名调用。被static声明的成员变量属于静态成员变量,静态变量存放在Java内存区域的方法区。调用格式:类名.静态变量名 类名.静态方法名()。

2. 静态代码块:静态代码块定义在类中方法外,静态代码块在非静态代码块之前执行(静态代码块→非静态代码块→构造方法)。该类不管创建多少对象,静态代码块只执行一次。

3. 静态内部类(static修饰类的话只能修饰内部类):静态内部类与非静态内部类之间存在一个最大的区别:非静态内部类在编译完成之后会隐含地保存一个引用,该引用是指向创建它的外围类,但是静态内部类没有。没有这个引用就意味着:(1)它的创建是不需要依赖外围类的创建;(2)它不能使用任何外围类的非static成员变量和方法。

4. 静态导包(用来导入类中的静态资源,1.5之后的新特性):格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中的静态成员,可以直接使用类中的静态成员变量和成员方法。

 

String、StringBuffer、StringBuilder

  • String:字符串常量(线程安全)
  • StringBuffer: 字符串变量(线程安全)
  • StringBuilder: 字符串变量(非线程安全)

首先,String是引用数据类型

String的源码

public final class String

    implements java.io.Serializable, Comparable<String>, CharSequence,Constable, ConstantDesc

String是final修饰的,不可以被继承。

String类实现的接口:

  1. java.io.Serializable:这个序列化接口仅用于标识序列化的语意。
  2. Comparable:这个compareTo(T 0)接口用于对两个实例化对象比较大小。
  3. CharSequence:这个接口是一个只读的字符序列。包括length(),charAt(intindex),subsequence(int start,int end)这几个API接口,StringBuffer和StringBuilder也实现了该接口。

             

StringBuffer和StringBuilder:

public final class StringBuffer extends AbstractStringBuilder

implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
------
public final class StringBuilder extends AbstractStringBuilder

implements java.io.Serializable,Comparable<StringBuilder>,CharSequence

StringBuffer和StringBuilder都继承了AbstractStringBuilder。StringBuffer很多方法都有synchronized关键字修饰,线程安全,而StringBuilder没有。因此StringBuilder的效率也更高。

 

 

int和Integer的区别

         说到int和Integer的关系,可以想到Integer是int的包装类,从1.5开始引入了自动装箱/拆箱机制,使二者可以相互转换。

         当给一个Integer对象赋一个int值时,会调用Integer类的静态方法valueOf。

public static Integer valueOf(int i) {

        if (i >= IntegerCache.low && i <= IntegerCache.high)

            return IntegerCache.cache[i + (-IntegerCache.low)];

        return new Integer(i);

}

     IntegerCache是Integer的一个静态内部类,它的作用是判断整型字面量的值,如果在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。

posted @ 2021-03-25 16:04  'Logan  阅读(56)  评论(0)    收藏  举报