Java语言有哪些特点?
简单易学、面向对象、平台无关性、可靠性、安全性、支持多线程、支持网络编程、编译与解释并存
什么是Java的虚拟机?
任何一种可以运行Java字节码的软件均可看成是Java的虚拟机
什么是字节码?采用字节码的最大好处是什么?
字节码是Java虚拟机的指令组,和CPU上的微指令很相似 。字节码最大的好处是可跨平台运行
什么是平台无关性?Java语言是怎样实现平台无关性的?
编写的应用程序不用修改就可以在不同的软硬件平台上运行。Java语言是靠JVM在目标代码级实现平台无关性的,可以说JVM是Java平台无关的基础
Java语言程序有几种?他们包含哪几个方面?
Application应用程序和Applet小程序
什么是Java程序的主类?
Java应用程序的主类必须包含一个定义为`public static void main(String[] args)`;Java小程序的主类必须是一个继承自系统JApplet或Applet的子类,且该类必须是public类。
Java语言定义了哪几种基本数据类型?
8种基本数据类型。byte, short, int, long, float, double, char
表示整数类型数据的关键字有哪几个?他们各占用几个字节?
byte, short, int, long分别占 1, 2, 4, 8个字节
单精度浮点float和双精度浮点double的区别是什么?
单精度浮点数的数据位是32位,双精度浮点数的数据位是64位,double的精度是float的两倍
字符型常量与字符串常量的主要区别是什么?
字符型常量是用一对单引号括起来的单个字符,字符串常量是用双引号括起来的一串若干个字符(可以是0个)
简述Java语言对定义标识符的规定有哪些。
标识符可以由字母、数字和下划线、美元符号等组合而成,标识符必须以字母、下划线或美元符号开头,不能以数字开头
Java语言采用何种编码方案?有何特点?
Unicode字符集编码方案,便于西文字符和中文字符的处理
什么是强制类型转换?在什么情况下需要强制类型转换?
强制类型转换就是将长数据转换为短数据。如果要将较长的数据转换成较短的数据时,就要进行强制类型转换。
自动类型转换得前提是什么?转换是从”短”到”长”的优先级顺序是怎样的?
转换前的数据类型与转换后的类型兼容,转换后的数据类型的表示范围比转换前的类型大。byte→short→char→int→long→float→double
数字字符串转换为数值型数据时,所使用的方法有哪些?
转换的方法 | 功能说明 |
---|---|
Byte.parseByte(String s) | 将数字字符串转换为字节型数据 |
Short.parseShort(String s) | 将数字字符串转换为短整型数据 |
Integer.parseInteger(String s) | 将数字字符串转换为整型数据 |
Long.parseLong(String s) | 将数字字符串转换为长整型数据 |
Float.parseFloat(String s) | 将数字字符串转换为浮点型数据 |
Double.parseDouble(String s) | 将数字字符串转让为双精度型数据 |
Boolean.parseBoolean(String s) | 将字符串转换为布尔型数据 |
写出由键盘输入数据的两种基本格式。
在1.5版本之前,Java用BufferedReader来读取输入数据,在1.5版本之后,Java用Scanner来读取输入数据
import java.io.*;
public class Buffer {
public static void main(String[] args) throws IOException {
String str;
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
str = buf.readLine();
}
}
import java.io.*;
import java.util.*;
public class Scan {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
double num = sc.nextDouble();
}
}
编写程序,从键盘上输入一个浮点数,然后将该浮点数的整数部分输出。
浮点数的输入用double或者float,第一种方法用BufferedReader来读,第二种方法用Scanner来读
import java.io.*;
public class Exercise {
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
double num = Double.parseDouble(buff.readLine());
int i = (int) num;
System.out.println(i);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double t = in.nextDouble();
int num = (int) t;
System.out.println(num);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a / b);
}
}
编写程序,从键盘上输入圆柱体的底半径r和高h,然后计算其体积并输出。
这里要用到Math.PI,假设题目给出的半径r和高h都是整形数值
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int r = in.nextInt();
int h = in.nextInt();
System.out.println(Math.PI * r * r * h);
}
}
Java语言有哪些基本的运算符?
算术运行符包括 +、-、*、/、%、++、--
关系运算符包括 >、<、>=、<=、==、!=
逻辑运算符包括 !、&&、||、&、|
位运算符包括 >>、<<、>>>、&、|、^、~
赋值运算符包括 =
条件运算符 ?:
分量运算符 .
下标运算符 []
实例运算符 instanceof
内存分配运算符 new
强制类型转换运算符 (类型)
方法调用运算符 ()
逻辑运算符中“逻辑与、逻辑或”和“简洁与、简洁或”的区别是什么?
非简洁运算在必须计算完左右两个表达式之后,才取结果值;而简洁运算可能只计算左边的表达式而不计算右边的表达式,即对于 &&,只要左边的表达式为 false,就不计算右边的表达式,则整个表达式为 false;对于 ||,只要左边表达式为 true,就不计算右边表达式,则整个表达式为 true。
逻辑运算符与位运算符的区别是什么?
位运算符的操作数只能为整型或字符型数据,虽然有的位运算符号(如 &、|、^)与逻辑运算符的写法相同,但逻辑运算符的操作数为boolean型的量
什么是运算符的优先级和结合性?
运算符的优先级决定了表达式中不同运算执行的先后顺序,运算符的结合性决定了并列的多个同级运算符的先后执行顺序
写出下列表达式的值,设x=3, y = 17, yn = true。
(1) x + y * x--
3 + 17 * 3; 54
(2) -x * y + y
-3 * 17 + 17; -34
(3) x < y && yn
3 < 17 && true; true
(4) x > y || !yn
3 > 17 || false; false
(5) y != ++x ? x : y
17 != 4 ? 4 : 17; 4
(6) y++ / --x
17 / 2; 8
(7) --y >>> 3
16 >>> 3; 2
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int score = in.nextInt();
switch (score / 10) {
case 10:
case 9:
System.out.println("优");
break;
case 8:
System.out.println("良");
break;
case 7:
System.out.println("中");
break;
case 6:
System.out.println("及格");
break;
default:
System.out.println("不合格");
break;
}
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int score = in.nextInt();
switch (score / 10) {
case 10:
case 9:
System.out.println("A");
break;
case 8:
if (score % 10 >= 5)
System.out.println("A");
else
System.out.println("B");
break;
case 7:
case 6:
System.out.println("C");
break;
default:
System.out.println("D");
break;
}
}
}
public class Exercise {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 7 == 0)
System.out.println(i);
}
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long sum = 0, temp = 1;
for (int i = 1; i <= n; i++) {
temp *= i;
sum += temp;
}
System.out.println(sum);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
double sum = 0;
int sign = 1, temp = 1;
for (int i = 1; i <= n; i++) {
temp *= i;
sum += sign * (1.0 / temp);
sign = -sign;
}
System.out.println(sum);
}
}
public class Exercise {
public static void main(String[] args) {
for (int i = 100; i <= 999; i++) {
int temp = i, sum = 0;
while (temp != 0) {
sum += Math.pow(temp % 10, 3);
temp /= 10;
}
if (sum == i)
System.out.println(i);
}
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
int sum = 0;
for (int i = 1; i < num; i++) {
if (num % i == 0)
sum += i;
}
System.out.println(sum == num);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
int sum = 0;
while (num != 0) {
sum += num % 10;
num /= 10;
}
System.out.println(sum);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double num = in.nextDouble();
int digital = (int) num;
System.out.println(digital + " " + (num - digital));
}
}
public class Exercise {
public static void main(String[] args) {
int day = 0;
double len = 3000;
while (len >= 5) {
len /= 2;
day++;
}
System.out.println(day);
}
}
public class Exercise {
public static void main(String[] args) {
int[][] matrix = new int[5][5];
int k = 1;
for (int i = 0; i < 5; i++) {
for (int j = 0; j <= i; j++)
matrix[i - j][j] = k++;
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5 - i; j++)
System.out.print(matrix[i][j] + " ");
System.out.println();
}
}
}
简述 Java 内存分配的机制。
Java 语言把内存分为两种:栈内存和堆内存。
在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配,当在一段代码块中定义一个变量时,Java 就在栈内存中为这个变量分配内存空间,当超出变量的的作用域后,Java 会自动释放掉为该变量分配的内存空间。
堆内存用来存放由 new 运算符创建的对象和数组,在堆中分配的的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中创建了一个数组或对象后,同时还在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,引用变量实际上保存的是数组或对象在堆内存中的地址(也称为对象的句柄),以后就可以在程序中使用栈的引用变量来访问堆中的数组或对象。
数组的主要特点:
- 数组是相同数据类型的元素的集合。
- 数组中的各元素是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。
- 数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如 a[0] 表示名字为 a 的数组中的第一个元素。
String 类的常用方法
方法 | 说明 |
---|---|
public int length() |
返回字符串的长度 |
public boolean equals(Object anObject) |
将给定字符串与当前字符串相比较,若两字符串相等,则返回 true,否则返回 false |
public String substring(int beginIndex) |
返回字符串中从 beginIndex 开始的子串 |
public String substring(int beginIndex, int endIndex) |
返回从 beginIndex 开始到 endIndex 的子串 |
public char charAt(int index) |
返回 index 指定位置的字符 |
public int indexOf(String str) |
返回 str 在字符串中第一次出现的位置 |
public String toLowerCase() |
将字符串中所有的字符都转换为小写字符 |
public String toUpperCase() |
将字符串中所有的字符都转换为大写字符 |
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] num = new int[n];
double aver = 0;
for (int i = 0; i < n; i++) {
num[i] = in.nextInt();
aver += num[i] * 1.0 / n;
}
for (int i = 0; i < n; i++) {
if (num[i] >= aver)
System.out.println(num[i]);
}
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
int temp = in.nextInt();
if (temp > max)
max = temp;
if (temp < min)
min = temp;
}
System.out.println("Max: " + max + "\n" + "Min: " + min);
}
}
int[][] matrix = new int[3][3];
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += matrix[i][i];
sum += matrix[2 - i][i];
}
public class Exercise {
public static void main(String[] args) {
int[][] matrix;
matrix = new int[][]{{12,23,34,15,7},{23,14,61,45,78},{3,12,43,54,65},{34,56,87,54,23}};
int minRow = 0, minCol = 0, maxRow = 0, maxCol = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
if (matrix[minRow][minCol] > matrix[i][j]) {
minRow = i;
minCol = j;
}
if (matrix[maxRow][maxCol] < matrix[i][j]) {
maxRow = i;
maxCol = j;
}
}
}
System.out.println("min: " + matrix[minRow][minCol] + "\n" + minRow + " " + minCol + "\n\n" + "max: " + matrix[maxRow][maxCol] + "\n" + maxRow + " " + maxCol);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
int[] num = new int[8];
Random random = new Random();
for (int i = 0; i < 8; i++) {
num[i] = random.nextInt() % 100;
}
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7 - i; j++) {
if (num[j] > num[j + 1]) {
int temp = num[j];
num[j] = num[j + 1];
num[j + 1] = temp;
}
}
}
for (int i = 0; i < 8; i++) {
System.out.print(num[i] + " ");
}
}
}
public class Exercise {
public static void main(String[] args) {
int[] ball = new int[30];
for (int j = 0, temp = 0; temp <= 15; temp++) {
int count = 1, i = j;
while (count < 13 || ball[i] == 1) {
if (ball[i] != 1)
count++;
i++;
if (i == 30)
i = 0;
}
ball[i] = 1;
j = i + 1;
if (j == 30)
j = 0;
}
for (int i = 0; i < 30; i++) {
System.out.print(ball[i] + " ");
}
}
}
public class Exercise {
public static void main(String[] args) {
System.out.println(args[0].equals(args[1]));
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.next();
int start = in.nextInt(), len = in.nextInt();
System.out.println(s.substring(start, start + len));
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.next();
char c = in.next().charAt(0);
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != c)
System.out.print(s.charAt(i));
}
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
int ch = 0, digital = 0, other = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
ch++;
else if (c >= '0' && c <= '9')
digital++;
else
other++;
}
System.out.println(ch + " " + digital + " " + other);
}
}
import java.util.*;
public class Exercise {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String data = "";
do {
data = in.nextLine();
if ("exit".equals(data))
break;
System.out.println(data);
} while (true);
}
}
类与对象的区别是什么?
类是对某一类事物的描述,是抽象的、概念上的定义;对象则是实际存在的属该类事物的具体的个体,对象是类的实例化,因而也称为实例(instance)。
如何定义一个类?类的结构是怎样的?
定义类实际上就是定义类的属性与方法。
// 类的一般结构如下:
[类修饰符] class 类名称
{
[修饰符] 数据类型 成员变量名称;
[修饰符] 返回值的数据类型 方法名(参数1, 参数2, ......)
{
语句序列;
return [表达式];
}
}
定义一个类时所使用的修饰符有哪几个?每个修饰符的作用是什么?是否可以混用?
定义一个类时所使用的修饰符有 4 个,一个类可以有多个修饰符,且无先后顺序之分,但 abstract 和 final 相互独立,所以不能同时应用在一个类的定义中,每个修饰符的作用如下:
修饰符 | 含义 |
---|---|
public |
将一个类声明为公共类,它可以被任何对象访问 |
abstract |
将一个类声明为抽象类,没有实现方法,需要子类提供方法的实现,所以不能创建该类的实例 |
final |
将一个类声明为最终类即非继承类,表示它不能被其他类所继承 |
缺省 |
缺省修饰符时,则表示只有在相同包中的对象才能使用这样的类 |
成员变量量的修饰符有哪些?各修饰符的功能是什么?是否可以混用?
成员变量的修饰符有 8 个,除了访问控制修饰符有多个外,其他的修饰符都只有一个,每个修饰符的功能如下:
修饰符 | 含义 |
---|---|
public |
公共访问控制符。指定该变量为公共的。它可以被任何对象的方法访问 |
private |
私有访问控制符。指定该变量只允许自己类的方法访问,其他任何类(包括子类)中的方法均不能访问此变量 |
protected |
保护访问控制符。指定该变量只可以被它自己的类及其子类或同一包中的其它类访问,在子类中可以覆盖此变量 |
缺省 |
缺省访问控制符。表示在同一个包中的其他类可以访问此成员变量,其他包中的类不能访问该成员变量 |
final |
最终修饰符。指定此变量的值不能改变 |
static |
静态修饰符。指定该变量被所有对象共享,即所有实例都可以使用该变量 |
transient |
过度修饰符。指定该变量是一个系统保留,暂无特别作用的临时性变量 |
volatile |
易失修饰符。指定该变量可以同时被几个线程控制和修改 |
成员方法的修饰符有哪些?各修饰符的功能是什么?是否可以混用?
成员方法的修饰符有 9 个,成员方法与成员变量同样有多个控制修饰符,当用两个以上的修饰符来修饰一个方法时,需要注意,有的修饰符之间是互斥的,所以不能同时使用。
修饰符 | 含义 |
---|---|
public |
公共访问控制符。指定该方法为公共的,它可以被任何对象的方法访问 |
private |
私有访问控制符。指定该方法只允许自己类的方法访问,其他任何类(包括子类)中的方法均不能访问此方法 |
protected |
保护访问控制符。指定该方法只可以被它的类及其子类或同一包中的其他类访问 |
缺省 |
缺省访问控制符。表示在同一个包中的其他类可以访问此成员方法,其他包中的类不能访问该成员方法 |
final |
最终修饰符。指定该方法不能被重载 |
static |
静态修饰符。指定不需要实例化一个对象就可以激活的方法 |
abstract |
抽象修饰符。指定该方法只声明方法头,而没有方法体,抽象方法需在子类中被实现 |
synchronized |
同步修饰符。在多线程程序中,该修饰符用于在运行前,对它所属的方法加锁,以防止其他线程访问,运行结束后解锁 |
native |
本地修饰符。指定此方法的方法体是用其他语言(如 C)在程序外部编写的 |
成员变量与局部变量的区别有哪些?
由类和方法的定义可知,在类和方法中均可定义属于自己的变量。类中定义的变量是成员变量,而方法中定义的变量是局部变量。
1. 从语法形式上看,成员变量是属于类的,而局部变量是在方法中定义的或是方法的参数;成员变量可以被 public、private、static 等修饰符所修饰,而局部变量则不能被访问控制符及 static 所修饰;成员变量和局部变量都可以被 final 修饰。
2. 从变量在内存中的存储方式上看,成员变量是对象的一部分,而对象是存在与堆内存中的,而局部变量是存在与栈内存中的。
3. 从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而产生,随着方法调用的结束而自动消失。
4. 成员变量如果没有被赋初值,则会自动以类型的默认值赋值(有一种情况例外,被 final 修饰但没有被 static 修饰的成员变量必须显式的赋值);而局部变量则不会自动赋值,必须显式地赋值后才能使用。
创建一个对象使用什么运算符?对象实体与对象的引用有何不同?
创建一个对象使用 new 运算符;对象实体是实在存在于堆内存中的,而对象的引用是管理对象实体的句柄存在于栈内存中。
对象的成员如何表示?
对象的成员通过对象名.对象成员来访问。
在成员变量或成员方法前加上关键字 this 表示什么含义?
this.成员名 表示 对象本身的成员。this 代表调用此成员的对象。
什么是方法的返回值?返回值在类的方法里面的作用是什么?
方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用:接收产生的结果,使得它可以用于其他的操作。
在方法调用中,使用对象作为参数进行传递时,是“传值”还是“传址”?对象作参数起到什么作用?
当参数是基本类型数据时,则是传值方式调用,而当参数是引用型的变量时,则是传址方式调用。
什么叫匿名对象?一般在什么情况下使用匿名对象?
当一个对象被创建之后,在调用该对象的方法时,也可以不定义对象的引用变量,而直接调用对象的方法,这样的对象叫做匿名对象。
使用匿名对象通常有如下两种情况:
1. 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
2. 将匿名对象作为实参传递给一个方法调用。
定义一个 Student 类,包含的内容如下:
成员变量:学号,姓名,性别,班干部否,数学,语文,外语
成员方法:输入,总分,平均分
编程实现这个类,并调用相应的方法输入数据,计算总分和平均分。
import java.util.*;
public class Student {
private String id;
private String name;
private String gender;
private String isLeader;
private int math;
private int chinese;
private int english;
public void input() {
Scanner in = new Scanner(System.in);
id = in.next();
name = in.next();
gender = in.next();
isLeader = in.next();
math = in.nextInt();
chinese = in.nextInt();
english = in.nextInt();
in.close();
}
public int total() {
return math + chinese + english;
}
public double aver() {
return total() / 3.0;
}
}
public void exercise(int[][] matrix, int m, int n) {
int[] sum = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
sum[i] += matrix[j][i];
}
System.out.println(sum[i]);
}
}
一个类的公共成员与私有成员有何区别?
私有成员无法从该类的外部访问到该类内部的成员,而只能被该类自身访问和修改,而不能被任何其他类包括该类的子类来获取或引用;公共成员则可以被其他的类访问。
什么是方法的重载?
重载是指在同一个类内具有相同名称的多个方法,这多个同名方法如果参数个数不同,或者是参数个数相同,但类型不同,则这些同名的方法就具有不同的功能。
方法的重载是实现“多态”的一种方法。
一个类的构造方法的作用是什么?若一个类没有声明构造方法,该程序能正确执行吗?为什么?
构造方法的作用是在对象被创建时初始化对象的成员的方法;如果一个类没有声明构造方法,该类也可以被正确实例化,Java 编译器会自动为该类生成一个默认的构造方法。
构造方法有哪些特性?
1. 构造方法的方法名与类名相同
2. 构造方法没有返回值,但不能加 void
3. 构造方法的主要作用是完成对类对象的初始化工作
4. 构造方法一般不能由编程人员显式地直接调用,而是用 new 来调用
5. 在创建一个类的对象的同时,系统会自动调用该类的构造方法为对象初始化
在一个构造方法内可以调用另一个构造方法吗?如果可以,如何调用?
可以;Java 语言允许在类内从某一构造方法内调用另一个构造方法;在某一构造方法内调用另一个构造方法时,必须使用 this 关键字来调用,否则编译时将出现错误,而且 this 关键字必须写在构造方法内的第一行的位置。
被 static 修饰的成员被称为静态成员,也称为类成员,而不用 static 修饰的成员称为实例成员。
静态变量与实例变量有哪些不同?
用 static 修饰符修饰的成员变量称为“静态变量”,静态变量也称类变量。静态变量是隶属于类的变量,而不是属于任何一个类的具体变量,静态变量不需要实例化就可以使用。
实例变量是隶属于对象的变量,是属于具体的一个对象的,是需要把类实例化为对象才可以使用的。
静态方法与实例方法有哪些不同?
用 static 修饰符修饰的方法是属于类的静态方法,又称为类方法。
静态方法实质是属于整个类的方法,而不加 static 修饰符的方法,是属于具体对象的方法。
在一个静态方法内调用一个非静态成员为什么是非法的?
静态方法是属于整个类的,所以它不能操纵和处理属于某个对象的成员,而只能处理属于整个类的成员,即静态方法只能访问静态成员变量或静态成员方法。
对象的相等与指向它们的引用相等,两者有什么不同?
对象的相等指的是对象的内容相等;
指向它们的引用相等指的是引用变量指向的地址相同;
== 操作符专门用来比较两个变量的值是否相等;
equals 方法是用于比较两个独立对象的内容是否相同。
什么是静态初始化器,其作用是什么?静态初始化器由谁在何时执行?它与构造方法有何不同?
静态初始化器是由关键字 static 修饰的一对大括号“{}”括起来的语句组。它是用来完成初始化工作的;静态初始化器有 Java 虚拟机在类初始化的时候一次执行;
静态初始化器与构造方法有以下几点不同:
1. 构造方法是对每个新创建的对象初始化,而静态初始化器是对类自身进行初始化。
2. 构造方法是在用 new 运算符创建新对象时由系统自动执行,而静态初始化器一般不能由程序来调用,它是在所属的类被加载入内存时由系统调用执行的。
3. 用 new 运算符创建多少个新对象,构造方法就被调用多少次,但静态初始化器则在类被加载入内存时只执行一次,与创建多少个对象无关。
4. 不同于构造方法,静态初始化器不是方法,因而没有方法名,返回值和参数。
子类将继承父类的所有成员吗?为什么?
不是;子类可以从父类那里继承所有非 private 的成员作为自己的成员。
在子类中可以调用父类的构造方法吗?若可以,如何调用?
可以;在子类的的构造方法中通过 super() 来调用父类特定的构造方法中。
在调用子类的构造方法之前,会先自动调用父类中没有参数的构造方法,其目的是什么?
目的是为了帮助继承自父类的成员做初始化操作。
在子类中可以访问父类的成员吗?若可以,用什么方式访问?
可以;在子类中使用 super 不但可以访问父类的构造方法,还可以访问父类的成员变量和成员方法,但 super 不能访问在子类中添加的成员。
用父类对象变量可以访问子类的成员吗?若可以,则只限于什么情况?
可以;通过父类的对象访问子类的成员,只限于“覆盖”的情况发生时。也就是说,父类与子类的方法名称、参数个数与类型必须是完全相同,才可以通过父类的对象调用子类的方法。
什么是“多态”机制?Java 语言中是如何实现多态的?
多态是指“一种定义,多种实现”,多态有两种表现形式:重载和覆盖;多态是由方法重载,方法重写,继承,自动转型等引起的一系列特性。
方法的“覆盖”与方法的“重载”有何不同?
重载是指在同一个类,内定义多个名称相同,但参数个数或类型不同的方法,从而,Java 系统便可根据参数的个数或类型,调用相对应的方法;
覆盖是指在子类中,定义名称、参数个数与类型均与父类完全相同的方法,用来重写父类中同名方法的操作。
this 和 super 分别有什么特殊含义?
super 是从子类调用调用父类的成员,包括构造方法、成员变量和成员方法。
this 是用来调用同一类内的成员,包括构造方法、成员变量和成员方法。
什么是最终类与最终方法?它们的作用是什么?
在默认情况下,所有的成员变量和成员方法都可以被覆盖,如果父类的成员不希望被子类的成员所覆盖就可以将它们声明为 final。如果用 final 修饰成员变量,则成员变量是最终变量,即常量;如果用 final 修饰成员方法,则该方法为最终方法;如果一个类被 final 修饰符所修饰,则说明这个类不能被其他类所继承,即该类不可能有子类,这种类被称为最终类。
什么是抽象类与抽象方法?使用时应注意哪些问题?
抽象类是以修饰符 abstract 修饰的类,抽象方法是以 abstract 关键字开头的方法,此方法只声明返回值的数据类型、方法名称与所需要的参数,但没有方法体。
需要注意的是:
1. 由于抽象类是需要被继承的,所以 abstract 类不能用 final 来修饰。也就是说,一个类不能既是最终类,又是抽象类,即关键字 abstract 与 final 不能合用。
2. abstract 不能与 private、static、final 或 native 并列修饰同一方法。
什么是接口?为什么要定义接口?
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能);
接口实现和类继承的规则不同,为了数据的安全,继承时一个类只有一个直接父类,也就是单继承,但是一个类可以实现多个接口,接口弥补了类的不能多继承缺点,继承和接口的双重设计既保持了类的数据安全也变相实现了多继承。
如何定义接口?接口与抽象类有哪些异同?
接口与抽象类有以下不同:
1. 接口的数据成员都是静态的,并且必须初始化。
2. 接口中的方法必须全部都声明为 abstract 的,也就是说,接口不能像抽象类一样拥有一般的方法,而必须全部是抽象方法。
接口定义的语法格式如下:
[public] interface 接口名称 [extends 父接口列表]
{
[public] [static] [final] 数据类型 成员变量名 = 常量;
[public] [abstract] 返回值的数据类型 方法名(参数表);
}
内部类的类型有几种?分别在什么情况下使用?它们所起的作用有哪些?
内部类分为: 成员内部类、局部内部类、静态嵌套类、匿名内部类 ;内部类的主要作用是将逻辑上相关的类放到一起;而匿名类是一种特殊的内部类,它没有类名,在定义类的同时,就生成该类的一个实例,由于不会在其他地方用到该类,所以不用取名字,因而又被称为匿名内部类。
内部类与外部类的使用有何不同?
内部类不能与外部类同名,否则编译器无法区分内部类与外部类。如果内部类还有内部类,则内部类的内部类不能与它的任何一层外部类同名。在封装它的类的内部使用内部类,与普通类的使用方式相同,但在外部引用外部类时,则必须在内部类名前冠以其所属外部类的名字才能使用。在用 new 运算符创建内部类时,也要在 new 前面冠以对象变量。
怎样使用匿名内部类对象?
匿名内部类是指可以利用内部类创建没有名称的对象,它一步完成了声明内部类和创建该类的一个对象,并利用该对象访问到类中的成员。匿名内部类的定义与创建该类的一个实例同时进行,即类的定义前面有一个 new 运算符,而不是使用关键字 class, 同时带上圆括号 “()” 表示创建对象。
创建匿名内部类的用意主要是用来弥补内部类中没有定义到的方法,并可有效地简化程序代码。
使用方法:
( // 创建匿名内部类,并执行所定义的方法
new 类名() // 括号 “()” 内不允许有参数
{
方法名(参数表)
{
方法体语句;
}
}
).方法名(参数表);
什么是包?它的作用是什么?如何创建包?如何引用包中的类?
包是 Java 语言提供的一种区别类名空间的机制,是类的组织方式,每个包对应一个文件夹,包中还可以在有包,称为包等级。创建一个包需要使用 package 语句,格式为:`package 包名 1[.包名 2[.包名 3]];`利用 import 语句引用 Java 定义的包及包中的类。
Java 语言中怎样清除对象?能否控制 Java系统中垃圾的回收时间?
当一个对象不被任何引用类型的变量使用时,它的内存就会被 Java 垃圾回收器回收清楚对象;Java 语言不允许通过程序强迫垃圾回收器立即执行。
什么是异常?简述 Java 语言的异常处理机制。
异常是指在程序运行中由代码产生的一种错误;
Java 语言的异常处理机制:
1. 发现异常:程序在运行过程中发生由与算法考虑不周或软件设计错误等导致的程序异常事件。
2. 抛出异常:程序在运行过程中,如果发生了异常事件,则产生代表该异常的一个“异常对象”,并把它交给运行系统,再由运行系统寻找相应的代码来处理这一异常。生成异常对象并把它提交给运行系统的过程称为抛出异常。
3. 捕获异常:抛出异常后,运行系统从生成异常对象的代码开始,沿方法的调用栈逐层回溯查找,直到找到包含相应异常处理的方法,并把异常对象提交给该方法为止,这个过程称为捕获异常。
Throwable 类的两个直接子类 Error 和 Exception 的功能各是什么?用户可以捕获到的异常是哪个类的异常?
Error 类及其子类的对象,代表了程序运行时 Java 系统内部的错误。即 Error 类及其子类的对象是由 Java 虚拟机生成并抛出给系统,这种错误有内存溢出错、栈溢出错、动态链接错等。通常 Java 程序不对这种错误进行直接处理,必须交由操作系统处理;
Exception 子类则是供应用程序使用的,它是用户程序能够捕捉到的异常情况;
用户可以捕捉的异常是 Exception 异常。
Exception 类有何作用?每个 Exception 类的对象代表什么?
Exception 类对象是 Java 程序抛出和处理的对象,它有各种不同的子类分别对应各种不同类型的异常。
什么是运行时异常?什么是非运行时异常?
Exception 类中的一个子类 RuntimeException 代表运行时异常,它是程序运行时自动地对某些错误做出反应而产生的;
除 RuntimeException 之外,其它则是非运行时异常,这种异常经常是在程序运行过程中由环境原因造成的异常。
抛出异常有哪两种方式?
1. 系统自动抛出的异常。
2. 指定方法抛出异常。
抛出异常时,为什么要在 catch() 括号内有一个变量 e ?
抛出异常时,throw 关键字所抛出的是由异常类所产生的对象,因此 throw 语句必须使用 new 运算符来产生对象,catch() 语句中的变量 e 是用来接收由 throw 关键字所抛出的由异常类所产生的对象。
在异常处理机制中,用 catch() 括号内的变量 e 接受异常类对象的步骤有哪些?
1. try 程序块若是有异常发生时,程序的运行便中断,并抛出“异常类所产生的对象”。
2. 抛出的对象如果属于 catch()括号内欲捕获的异常类,则 catch 会捕捉此异常,然后进到 catch 的块里继续运行。
3. 无论 try 程序块是否有捕捉到异常,或者捕捉到的异常是否与 catch()括号里的异常相同,最后一定会运行 finally 块里的程序代码。finally 的程序代码块运行结束后,程序再回到 try-catch-finally 块之后继续执行。
在什么情况下,方法的头部必须列出可能抛出的异常?
在方法内没有使用 try-catch 语句捕获异常,且方法内可能会产生异常时,则必须在声明方法的头部列出可能抛出的异常。
若 try 语句结构中有多个 catch() 子句,这些子句的排列顺序与程序执行效果是否有关?为什么?
有关;由于异常对象与 catch 块的匹配是按照 catch 块的先后排列顺序进行的。若将子类异常的 catch 语句块放在父类异常 catch 语句块的后面,则编译不能通过。
什么是抛出异常?系统定义的异常如何抛出?用户自定义的异常又如何抛出?
程序在运行过程中,如果发生了异常事件,则产生代表该异常的一个“异常对象”,并把它交给运行系统,再由运行系统寻找相应的代码来处理这一异常。生成异常对象并把它提交给运行系统的过程称为抛出异常;
所有系统定义的运行时异常都可以由系统自动抛出;
用户自定义的异常不能由系统自动抛出,因而必须借助于 throw 语句来定义何种情况算是产生了此种异常对应的错误,并应该抛出这个异常类的对象。
系统定义的异常与用户自定义的异常有何不同?如何使用这两类异常?
系统定义的异常类主要用来处理系统可以预见的较常见的运行时错误,对于某个应用程序所持有的运行时异常错误,则需要编程人员根据程序的特殊逻辑关系在用户程序里自己创建用户自己定义异常类和异常对象。用户自定义异常类主要用来处理用户程序中可能产生的逻辑错误,使得这种错误能够被系统及时识别并处理,而不致于扩散产生更大的影响,从而使用户程序有更好的容错性能,并使整个系统更加稳定。