一、面向对象和面向过程的区别
1. 面向过程 : 面向过程性能比面向对象高。因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考虑因素时(例如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发),但是,面向过程没有面向对象易维护、易复用、易扩展。
2.面向对象 : 面向对象易维护、易复用、易扩展。因为面向对象有封装、继承、多态性的特性,所以可以设计出低耦合的系统,使系统更加灵活、更加易于维护。但是面向对象的性能比面向过程低。
说明:这个并不是根本原因,面向过程也需要分配内存,计算内存偏移量,Java性能差的主要原因并不是因为它是面向对象语言,而是Java是半编译语言,最终的执行代码并不是可以直接被CPU执行的二进制机械码。而面向过程语言大多都是直接编译成机械码在电脑上执行,并且其它一些面向过程的脚本语言性能也并不一定比Java好。
二、关于JVM、JDK和JRE最详细通俗的解答
- JVM
java虚拟机(JVM)是运行java字节码的虚拟机。JVM有针对不同系统的特定实现(Windows、Linux、MacOS),目的是使用相同的字节码,它们都会给出相同的结果。
2. 什么是字节码?采用字节码的好处是什么?
在java中,JVM可以理解的代码就叫做 字节码 (即扩展名为.class的文件),它不面向任何特定的处理器,只面向虚拟机。java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同事又保留了解释型语言的可移植性的特点。所以java程序运行时比较高效,而且由于字节码并不针对一种特定的机器,因此java程序无须重新编译便可在多种不同的操作系统下运行。
2. 1 java程序从源代码到运行的执行步骤:
说明: 特别注意的是.class到机器码这一步,在这一步JVM类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对较慢。而且有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了JIT编译器,而JIT属于运行时编译。当JIT编译器完成第一次编译之后,其会将字节码对应的机器码保存下来,下次可以直接使用。
2.2 JDK
JDK是Java Development Kit,它是功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。
2.3 JRE
JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序。
3. java和c++的区别?
3.1 都是面向对象的语言,都支持封装、继承和多态。
3.2 java不提供指针来直接访问内存,程序内存更加安全。
三、重载和重写的区别
3.1、重载: 发生在一个类中,方法名称必须相同,参数类型不同,个数不同,顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
3.2、重写: 发生在父子类中,方法名、参数列表必须相同,返回值的范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。如果父类的方法访问修饰符为private,那么子类就不能重写改方法。
想要了解领取更多关于java知识点的可以点击下方链接
java资料包pan.baidu.com提取码:poom
四、Java 面向对象编程三大特性: 封装 继承 多态
4.1、封装:
封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。
4.2、继承:
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
继承说明:
5.2.1、 子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
5.2.2、 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
5.2.3、 子类可以用自己的方式实现父类的方法。(以后介绍)。
4.3、多态:
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。
五、String、StringBuffer和StringBuilder的区别
5.1 可变性
String类中使用了final关键字修饰字符数组来保存字符串(private finalchar value[ ]),所以String对象时不可变的。而StringBuffer和StringBuilder都是继承AbstractStringBuilder类,在AbstractStringBuilder类中没有使用final关键字修饰,所以这两种对象时可变的。(他们两个的构造方法都是使用的是父类的构造方法)。
5.2 线程安全性
String中的对象时不可变的,故String对象时线程安全的。
AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
5.3 性能
StringBuilder > StringBuffer > String
相同情况下StringBuilder 仅能比StringBuffer 获得10%-15%的性能,但却要冒多线程不安全的风险。
5.4 总结
5.4.1 操作少量的数据: 适用String
5.4.2 单线程操作字符串缓冲区下操作大量数据: 适用StringBuilder
5.4.3 多线程操作字符串缓冲区下操作大量数据: 适用StringBuffer
六、在一个静态方法内调用一个非静态成员为什么是非法的?
因为静态方法从程序编译完成时就已经存在了,而非静态成员得先通过实例化才能存在,那么如果在一个静态方法里调用了一个非静态成员,就有可能这个非静态成员压根还没实例化出来,程序也就无法得知是个啥,所以必须是非法的。
七、接口和抽象类的区别
8.1、 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),而抽象类可以有非抽象的方法。
8.2、 接口中除了static、final变量,不能有其他变量,而抽象类中则不一定。
8.3、 一个类可以实现多个接口,但只能实现一个抽象类。接口自己本身可以通过extends关键字扩展多个接口。
8.4、 接口方法默认修饰符是public,抽象方法可以有public、protected和default这些修饰符(抽象方法就是为了被重写所以不能使用private关键字修饰!)。
8.5、 从设计层面来说,抽象是对类的抽象,是一种模板设计,而接口是对行为的抽象,是一种行为的规范。
八、成员变量与局部变量的区别有哪些?
9.1、 从语法形式上看:成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;但是,成员变量和局部变量都能被 final 所修饰。
9.2、 从变量在内存中的存储方式来看:如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用static修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。
9.3、 从变量在内存中的生存时间上看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
9.4、 成员变量如果没有被赋初值:则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值。
九、== 与 equals区别(重要)
10.1、==
它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)。
10.2、equals()
它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1: 类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2: 类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
例子展示:
public class test1 { public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true System.out.println("aa==bb");
if (a == b) // false,非同一对象 System.out.println("a==b");
if (a.equals(b)) // true System.out.println("aEQb");
if (42 == 42.0) { // true System.out.println("true");
}
}
}
说明:
1、 String 中的 equals 方法是被重写过的,因为 object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。
2、 当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。
java资料包pan.baidu.com提取码:poom