1、面向过程:性能较高。面向过程语言大多是可以直接编译成机械码,直接就能在电脑上运行;而面向过程语言在运行时需要进行类的实例化,开销大并且消耗资源;而对于Java语言的性能较差问题,主要原因是它属于半编译语言,最终的执行代码不是可以直接被CPU执行的二进制机械码。
2、面向对象:易维护,易复用,易拓展。这些优点完全建立在面向对象语言的三大特性之上的,我不说大家应该都耳熟能详了,也就是封装,继承,多态,也正是基于此,我们才能用Java语言设计成低耦合的系统,是系统更加灵活。
1、面向对象(封装继承多态)
2、平台无关性(Java虚拟机实现了一次编译,多次运行)
3、可靠性
4、安全性
5、支持网络编程
6、编译与解释并存
1、JVM:是运行java字节码的虚拟机。多系统多实现(windows,Linux,macOS等),设计的目的是为了使用相同的字节码,产生一直的运行效果,即俗话说的一次编译,到处运行。
我们需要着重理解的是.class–>机器码这一步,JVM类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这样的效率十分慢,并且有的方法和代码是需要多次执行的(也就是我们常说的热点代码块)。因此就衍生出了JIT编译器,它是运行时编译,首先字节码文件编译一次,然后将编译好的二进制机器码保存好下次使用,而我们知道,机器码的运行效率肯定高于Java解释器,这也充分说明了Java是编译与解释共存的语言。
2、JDK: Java开发工具包。拥有JRE所拥有的的一切,还有编译器(javac)和工具,它能够创建和编译程序。
3、JRE:Java运行时环境。它是运行已编译Java程序所需的所有内容的集合。包括JVM,java类库,java命令和其他一些基础组件,但是,它不能用于创建新程序。
1、都是面向对象语言,支持封装继承多态
2、Java不提供指针来直接访问内存,程序内存更安全
3、Java的类是单继承的,C++实现多继承;虽然Java到的类不可以多继承,但是接口可以实现多继承。
4、Java有自动内存管理机制,不需要程序员手动释放内存。
5、在C语言中,字符串用‘\0’来标识结束,但是java中没有结束符概念。
1、应用程序的启动入口是main()方法。
2、小程序的启动入口是init()或run()方法。
1、重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同。
2、重写:发生在子类中,是子类对父类的允许访问的方法的实现过程进行重新编写,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。另外,私有方法(private修饰)不可被重写。一句话总结,方法提供的行为改变,方法的外貌没有改变。
1、封装:把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。
2、继承:使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。三大要点:1.子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。2.子类可以拥有自己属性和方法,即子类可以对父类进行扩展。3.子类可以用自己的方式实现父类的方法(方法重写)。
3、多态:指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定。通俗讲,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。实现多态的方式(Java):继承和接口
1、可变性:String类中使用final关键字修饰的字符数组来保存字符串。private final char value[]。后两者都继承AbstractStringBuilder类,这个类也是用字符数组保存字符串,但是没有用final关键字修饰,所有这连个对象是可变的。
2、线程安全性:String对象是不可变的,也就可以理解为常量,线程安全;StringBuffer对方法加了同步锁,所以线程安全;而StringBuilder没有加锁,所以非线程安全。
3、性能:StringBuilder > StringBuffer > String
每次对String类型进行改变时,都会生成一个新的String对象,然后将指针指向新的String对象内存地址。因此最慢。
StringBuilder虽然比StringBuffer性能提升了10~15%作用,但是要冒多线程不安全的风险。
4、使用总结:1.操作少量数据,用String。2.单线程操作字符串缓冲区下操作大量数据,使用StringBuilder 3.多线程操作字符串缓冲区下操作大量数据,使用StringBuffer
1、Java程序在执行子类的构造方法之前,如果没有用**super()**来调用父类特定的构造方法,那么程序默认取父类的无参构造方法。但是父类中没有无参构造方法,就会编译报错了。解决方案以下二选一即可:
、2父类中补上一个无参构造方法
3、在子类中使用**super()**方法调用父类一个特定的有参构造。
1、接口的方法默认是public,所有方法在接口中不能有实现(java 8 开始接口方法可以有默认实现),而抽象类可以有非抽象的方法。
2、接口方法默认修饰符是public,抽象方法可以有public、protected和default这些修饰符(抽象方法就是为了被重写所以不能使用private关键字修饰!)
3、接口中变量必须是public static final 修饰,而抽象类中不一定。
4、一个类可以实现多个接口,但只能实现一个抽象类。
5、从设计层面来讲,抽象是对类的抽象,是一种模板设计;接口是对行为的抽象,是一种行为规范。
1、从语法形式上看,成员变量属于类,局部变量属于局部代码块。成员变量可以被public,private,static等修饰符修饰,而局部变量不可被修饰;但是都能被final关键字修饰。
2、从变量在内存中的存储方式来看:如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用static修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存。
3、从变量在内存中的生存时间上看:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
4、成员变量如果没有被赋初值:则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
帮助子类完成初始化工作。
1、== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象(基本数据类型比较的是值,引用数据类型比较的是内存地址)。
2、equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
为什么要有 hashCode
我们先以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode: 当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
通过我们可以看出:hashCode() 的作用就是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode()在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
1、如果两个对象相等,则hashcode一定也是相同的
2、两个对象相等,对两个对象分别调用equals方法都返回true
3、两个对象有相同的hashcode值,它们也不一定是相等的
4、因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
5、hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)