答: java程序的源代码是解释性的,但.java文件要通过2个步骤才能变成机器语言: 1)在java平台上被编译成字节码(bytecode)的.class形式,这是二进制的JVM的机器语言。 2)JVM附带解释器,对这些字节码解释执行。 PS:Java的.class文件可以在任何平台上JVM运行!反之,离开了JVM的环境,.class的二进制字节码无法适用于任何平台。 PS2:在JDK-11的JRE支持cmd下直接用java xx.java直接运行java文件,不需要javac编译再运行
答:java支持Internet应用开发,包含java.net接口,提供了许多web开发的类库,包括URL,URLConnection,Socket,ServerSocket等等。还有Java RMI支持远程调用Java对象方法。这样可以在对等的两端激活远程方法,这也可以发生在客户端和服务器之间。这些都是分布式应用开发的有利工具。
UML就是统一建模语言,分为静态,动态和物理图。 静态图Static Diagram,描述不发生任何变化的软件元素的逻辑结构。描绘类,对象,数据结构及其中关系。 …
答: 外部类只能继承一次父类,然而内部类提供了继承的多重实现! 非静态内部类的成员变量初始化,就如同非静态方法与成员变量一样,依赖于外部类的实例化。JVM分配内存时,static类,方法以及成员变量优先分配,然而内部类的static成员变量缺少实例化的内部类无法分配内存。
答: 枚举类的实现有3个特点: 1) 所有的实例要用public static final来修饰并作为成员属性保存,实例名大写+下划线组成 2) 构造器用private隐藏 3) 提供一些static方法来供其他程序访问实例。
答: 1)enum和class interface平级,enum继承的是Enum类 2)所有实例必须放根大括号{}内第一行,用逗号分隔,名称大写 3)enum构造器private隐藏 4)enum类无法被继承,也没被继承的意义 5)enum类占用内存是手动枚举类的2倍以上,对Android编程敏感
抽象就是忽略当前与目标无关的方面,不打算了解全部,只取其部分特征。 抽象用于过程抽象与数据抽象。 数据抽象针对对象属性,比如鸟有翅膀,脚,羽毛。 过程抽象针对对象行为,比如鸟会飞。
继承就是子类能够继承超类的特征和行为,即超类的方法与实例变量能够被继承。
封装数据与操作数据的方法,限制未经过授权的访问操作数据。
多态性是抽象与继承的实现,包含函数与运算符的重载。前者参数多态,后者强制或隐式转换。 还有一种是包含的多态,即同一操作同时用于子类型与父类。
String长度不变,Stringbuffer可变。 而且Stringbuffer支持多线程,即线程安全,链接字符串使用Append就行。 String不支持线程,且每次+的过程中生产对象。
异常表示程序运行过程中可能出现非正常状态,运行时异常表示虚拟机操作中可能的异常。Java编译器要求申明抛出可能发生的非运行时异常,但不要求必须声明抛出未被捕获的运行时异常。但是并不要求必须声明抛出未被捕获的运行时异常。
Java虚拟机运行时的数据分为6种: 1.程序计数器:是一个数据结构,用于保存当前正常执行的程序内存地址。Java虚拟机的多线程通过线程轮流切换并分配处理器时间来实现的,为了线程切换后能恢复到正确的位置,每条线程需要一个独立的程序计数器,也就是该区域线程私有。
Java虚拟机栈:线程私有的,与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。局部变量表放着基本数据,操作栈,方法返回值。局部变量放着基本数据类型,还有对象的引用。本地方法栈:跟虚拟机栈很像,使用native方法Java堆: 所有线程共享一块内存区域,对象实例几乎都在这分配内存。方法区:各线程共享的区域,储存虚拟机加载类的信息,常量,静态变量,编译后的代码。运行时常量池:代表运行时每个class文件中的常量表。包括几种常量,方法或者域的引用允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同采取不同的行为方式(发送消息就是函数调用)。有以下优点:
可替换性:多态对已存在代码具有可替换性可扩充性:增加新的子类不影响已经存在的类结构接口性: 多态是超类通过方法签名,向子类提供一个公共平台接口,由子类来完善或者重写方法。实现多态主要有以下三种方式:
接口实现继承父类的重写方法同一类中进行方法重载接口的意义用三个词:规范,扩展,回调。
不能。重写只适用于实例方法,子类中含有父类相同签名的静态方法叫做隐藏。
不可变对象指被创建后状态不能改变,任何修改都会创建一个新的对象。 如String与包装类
静态变量存储在方法区,属于类所有。实例变量存储在堆当中,其引用存在当前线程栈。
当然可以,但是不要共享对象的引用,如果需要变化时,就返回对象的一个拷贝。最常见的例子就是对象中包含一个日期对象的引用。
可以用于byte但是不能用于long
返回false; 编译中,编译器会将s2直接优化为“ab”,将其放在常量池里,换而言之,s1==s2返回true! s5是一个新的对象,创建在堆。
&& 是 逻辑运算符中的与,即两边表达式皆为true,结果才为true & 和&&的区别在于,&会计算两边表达式,&&只要一边表达式为false则停止计算另一边表达式 &在两边表达式不为&时会进行按位与计算,结果转换为比如 0x0 & 0x1 结果为0
在java代码体中,我们用break跳出当前循环体,如果想要跳出多重, 那么只要在想要跳出的循环体前和break后加标号即可。
switch (expr1){ case expr2: action; }语句中的参数只支持int,String,enum 但是byte,short,char都可以隐式转换为int,故byte可以,long不可以
(1)可变与不可变:String是不可变字符串对象,StringBuilder和StringBuffer是可变字符串对象(其内部的字符数组长度可变)。
(2)是否多线程安全:String中的对象是不可变的,也就可以理解为常量,显然线程安全。StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是StringBuffer 中的方法大都采用了synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是非线程安全的。
(3)String、StringBuilder、StringBuffer三者的执行效率: StringBuilder > StringBuffer > String 当然这个是相对的,不一定在所有情况下都是这样。比如String str = “hello”+ "world"的效率就比 StringBuilder st = new StringBuilder().append(“hello”).append(“world”)要高。因此,这三个类是各有利弊,应当根据不同的情况来进行选择使用: 当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式; 当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。
final是一个修饰符,在修饰不同对象时发挥的作用不同
final修饰的数据只能进行一次赋值操作,对于基本变量,变量赋值后不可更改。对于引用变量,引用的对象的地址不可改,但是引用对象的属性是可以修改的。final修饰方法参数时,被传入的变量的值或者引用对象(地址)在方法体内是不可更改的。final修饰方法时,表示该方法无法覆盖,即不能被Overridefinal修饰类时,类不能被继承1)在类中,基本类型a申明是成员变量,随着类的实例化存于堆中,所在地址存放1这个字面量的值。 2)在方法中,基本类型a申明是局部变量,随着方法运行存于栈中,所在地址存放1这个字面量的值。
Integer a = 1 是自动装箱,等于 Integer a = Integer.valueOf(1)。 该静态方法返回一个(在堆中缓存数组里的)Integer(1)实例。 无论在类中还是方法中,引用类型a赋值后即引用Integer(1)这个对象地址。 区别在于: 1)在类中,引用类a是成员变量,申明时存在堆中 2)在方法中,引用类a是局部变量,申明时存在栈中
方法区存储类型(class,interface,enum,annotation)信息:
1) 完整有效名 (包名.类名) 2)直接父类的完整有效名(Object除外) 3)类型修饰符 (public,final,abstract) 4)类直接接口的有序列表 5)常量池 (每个类用到的字面量集合,包括字符串,整数,浮点数,以及符号引用) 6) 域信息 (名称,类型,修饰符) 7)方法信息 (名称,返回类型,参数表,修饰符) 8)静态变量
堆内存:
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。非堆内存:
VM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。