第一,&运算符有两种用法:(1)按位与;(2)逻辑与
第二,&&运算符是短路与运算符。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true,但是短路与运算,如果&&左边的表达式的值false,右边的表达式会被直接短路掉,不会再进行运算。(注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此)
2.break ,continue ,return 的区别及作用第一,break 跳出总上一层循环,不再执行循环(结束当前的循环体)
第二,continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
第三,return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
3.在 Java 中,如何跳出当前的多重嵌套循环在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如:
public static void main(String[] args) {
ok:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5) {
break ok;
}
}
}
}
4.final finally finalize区别
final:
第一,如果一个类被声明为final,那也就是意味着他不能再派生出新的子类,不能作为父类被继承,因此一个类不能既被声明为abstract,又被声明为final。(被final修饰的类不可以被继承)
例:String ,integer,Long等类都是final修饰的类,其保存值的属性也是final修饰的。
第二,将变量或者方法声明为final,可以保证他们在使用中不被改变。那也就是,被final声明的变量必须在声明时给定初始值,而且在以后的引用中只能读取,不可修改。被final修饰的方法也同样只能使用不能被重写。
第三,如果被final修饰的是一个基本数据类型的数据,一旦赋值后就不能再次更改,而对引用类型变量而言,它仅仅保存的是一个引用,所以呢引用的地址不会发生改变,也就是一直引用这个对象,但是这个对象属性是可以改变的,或者说成引用指向的内容是可以改变的,
finally:finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码放在finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。比如:关闭流,关闭socket。
finalize:第一,finalize是在Object类中定义的,finalize是一个方法,属于Object类的一个方法,该方法一般由垃圾回收器来调用,也就是说你的这个垃圾回收器要确定你的这个对象没有被引用,如果现在没有被引用,我就可以调用方法给他处理掉。也就是我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾。
第二,finalize方法,是在垃圾回收器删除对象之前对这个对象调用的,但是这个方法在工作中最好别用,如果用了可能会带来意向不到的难题,一般情况下,我们在业务
中不会自己实现这个方法。
第三,使用finalize大致过程:
1.垃圾回收器发现该对象实现了finalize()方法,就会把它添加到引用队列中。 2.Finalize线程会处理这个队列,将里面的对象逐个弹出,并调用他们的finalize()方法。 3.finalize()方法调用完后,Finalize线程会将引用从Finalize类中去掉,因此在一下轮GC中,这些对象就可以被回收了。 1.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?s1 + 1,s1是short类型,1是int型,s1会自动转换为int型的1,与1相加后,得到int型的2,要向左侧的short类型的s1看齐,即需要通过强制类型转换。正确写法:s1 = (short) (s1 + 1);
执行s1+=1;+=是 java 语言规定的运算符,java 编译器会对它进行特殊
处理,因此可以正确编译,其实执行的是s1 = (short) (s1 + 1); 其中会有一个强制转换的过程。
面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。面向过程注重的是每一个的顺序和步骤(函数)。
面向对象是模型化(模块化),面向对象注重事情有哪些对象,分成了哪几个模块,这个模块或者对象干了些什么。
(补充)两者的优点:面向过程直接高效,面向对象易于重复,扩展和维护。
面向对象三大特性:
封装:把一个对象的属性私有化,,允许外部调用所有的成员函数和数据项,外部不需要关心 内部是怎么实现的。
继承:让子类去继承,子类可以直接使用父类的属性和方法,不用自己再去定义了,扩展自己 个性化就可以了。
多态:首先要满足的三个条件(1)继承(2)方法重写(3)父类引用指向子类对象
3.成员变量与局部变量的区别有哪些第一,变量:它是在程序执行的过程中,在某个范围内其值可以发生改变的量。(本质上来说,变量其实是内存中的一小块区域)
成员变量(实例变量):定义在方法的外部,类的内部的变量 局部变量:定义在方法中的变量 二者对比:(1)作用域
成员变量:针对整个类有效
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
(2)初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值
(3)生命周期
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:当方法调用完,或者语句结束后,就自动释放。
(4)存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束 后,就自动释放。
第一,:它的作用是判断两个对象的地址是不是相等,也就是判断两个对象是不是一个对象。(基本数据类型比较的是值,引用数据类型==比较的是内存地址)
第二,equals():它的作用也是判断两个对象是否相等,他一般分两种使用情况:
情况1:类没有重写 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
public boolean equals(Object obj) {
return (this == obj);
}
情况2:类重写了 equals() 方法。一般,我们都重写 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
两者对比: ==是一个操作符,不能重写,而且大多被用在基础类型的比较上,因为基础类型不能使用equals方法。
equals是个方法,而且是Object的方法,在JAVA中,所有的类都是Object的子类,故所有对象都有 equals方法。
package com.briup.work;
public class test1 {
public static void main(String[] args) {
String a = new String ("ab");
String b = new String("ab");
String aa = "ab";
String bb = "ab";
if(a==b) {
System.out.println("a==b");
}else{
System.out.println("a对象不等于b对象");
}
if(aa==bb) {
System.out.println("aa==bb");
}else {
System.out.println("aa不等于bb");
}
if(42 == 42.0) {
System.out.println("true");
}
if(a.equals(b)) {
System.out.println("相等");
}else {
System.out.println("不相等");
}
}
}
5.请编写冒泡排序
public class MaoPaoPX {
public static void main(String[] args) {
int []arr= {3,88,8,10,7};
//轮数
for(int i=0;iarr[j+1]) {
arr[j]=arr[j]^arr[j+1];
arr[j+1]=arr[j]^arr[j+1];
arr[j]=arr[j]^arr[j+1];
}
}
System.out.println(Arrays.toString(arr));
}
}
}
冒泡排序(从小到大):比较相邻的元素,也就是一次比较两个元素,如果他们的顺序不是从小到大就把他们交换过来,一直重复地进行直到没有再需要交换的,那时也就是我们的这个数列已经完成排序。(这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。)
6.抽象类能使用 final 修饰吗?不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类
1.描述以下代码的输出结果public class A{
public A(){
System.out.println("A");
}
}
class B extends A{
public B(){
System.out.println("B");
}
}
class Test{
public static void main(String[] args){
new B();
System.out.println("-----------");
new A();
}
}
A B ----------- A注:调用子类构造器的时候会默认调用父类构造器。 2.数组有没有 length()方法?String 有没有 length()方法
数组没有 length()方法 ,有 length 的属性。String 有 length()方法。Javascript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。
3. 值传递和引用传递有什么区别值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。
引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。
4.构造器(constructor)是否可被重写(override)不能,因为构造器不能被继承,因此不能被重写,但是可以被重载。
5.重载(Overload)和重写(Override)的区别。一.方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
二.重载:被重载的方法必须改变参数列表(参数个数或类型或顺序不一样); 被重载的方法可以改变返回类型; 被重载的方法可以改变访问修饰符; 被重载的方法可以声明新的或更广的检查异常; 方法能够在同一个类中或者在一个子类中被重载。 无法以返回值类型作为重载函数的区分标准。
三.重写:参数列表必须完全与被重写方法的相同; 返回类型必须与被重写方法的返回类型相同或者子类方法的返回值是父类方法中返回值的子类型; 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么 在子类中重写该方法就不能声明为protected。 父类的成员方法只能被它的子类重写。 声明为final的方法不能被重写。 声明为static的方法不能被重写,但是能够被再次声明。 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新 的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。 构造方法不能被重写。 如果不能继承一个方法,则不能重写这个方法。
6.按照如下要求,完成代码假设要为某个公司编写雇员工资支付程序:
一般工人(Worker)按每月工作的天数计算工资;
销售人员(Salesman)在基本工资基础上每月还有销售提成;
经理(Manager) 每月按固定工资支付; 临时工(Floater )按小时支付;
要求:设计父类(Employee)描述所有雇员的共同特性(如姓名,性别,出生日期,员工类别),含有 计算工资的父类方法computeSalay,方法中可以是空实现,所有员工用该方法计薪。要求用多态实现。
public abstract class Employee {
private String name;
private String gender;
private Date brithday;
private String type;
private double salary;
public void setGender(String gender) {
this.gender = gender;
}
public void setBrithday(Date brithday) {
this.brithday = brithday;
}
public void setType(String type) {
this.type = type;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getName() {
return name;
}
public String getGender() {
return gender;
}
public Date getBrithday() {
return brithday;
}
public String getType() {
return type;
}
public double getSalary() {
return salary;
}
public void setName(String name) {
this.name = name;
}
public abstract double computeSalay();
}
public class Worker extends Employee {
private int day;
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
@Override
public double computeSalay() {
return getSalary() * day;
}
}
public class Salesman extends Employee {
private double commission;
public double getCommission() {
return commission;
}
public void setCommission(double commission) {
this.commission = commission;
}
@Override
public double computeSalay() {
return getSalary() + getSalary() * commission;
}
}
public class Manager extends Employee {
@Override
public double computeSalay() {
return getSalary();
}
}
public class Floater extends Employee {
private int hours;
public int getHours() {
return hours;
}
public void setHours(int hours) {
this.hours = hours;
}
@Override
public double computeSalay() {
return hours * getSalary();
}
}
7.分析以下代码是否能通过编译
public class A{
protected int test(){
return 0;
}
}
class B extends A{
public long test(){
return 0L;
}
}
不能通过编译;两个test方法方法名相同 且分别出现在子父类中;这样只能方法方法重写或者重载(一个类 中不允许出现没有任何关系的同名方法),但是再检查参数列表也相同,只能是方法重写。权限修饰符也 符合重写的语法规则,但是返回值类型不符合重写的语法规则(返回值可以相同也可以是父类方法返回 值的子类型 但是这里的 int 与 long 类型并无任何关系)所以违反重写的语法规则。
8.基本数据的包装类分别是什么byte – Byte
short – Short
int – Integer
long – Long
float – Float
double – Double
char – Character
boolean --Boolean
9.写出以下程序的输出结果Integer i1 = new Integer(97);//堆里开辟空间 0x11 Integer i2 = new Integer(97);//堆里空间 0x12 //比较引用地址 System.out.println(i1 == i2);//false //重写过 值比较value System.out.println(i1.equals(i2)); //true
Integer i3 = new Integer(148); Integer i4 = new Integer(148); //比较引用地址 System.out.println(i3 == i4);//false //重写过 值比较value System.out.println(i3.equals(i4));//true
//jdk1.5自动装箱 1.Integer.valueOf() 2. new Integer() -> intValue Integer i5 = 97; Integer i6 = 97; //-128-127缓存了地址 System.out.println(i5 == i6);//true //重写了方法 System.out.println(i5.equals(i6));//true
Integer i7 = 148; Integer i8 = 148; //没缓存,执行new Integer(),也就是说它们会分别创建两个不同的对象 System.out.println(i7 == i8);//false System.out.println(i7.equals(i8));//true //基本数据类型 == 比较的是数值 int a = 148; int b = 97; Integer c = 97; //一个Integer 与 int比较,先将Integer转换成int类型,再做值比较,所以返回的是true。 System.out.println(i7==a);//true System.out.println(b==c);//true10.分析以下代码的运行结果
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
String str4 = new String("hello");
String str5 = "hellohello";
String str6 =str1+str2;
System.out.println("str1==str2?"+(str1==str2));//true
System.out.println("str2==str3?"+(str2==str3));//false
System.out.println("str3==str4?"+(str3==str4));//false
System.out.println("str2.equals(str3)?"+(str2.equals(str3)));//true
System.out.println("str3.equals(str4)?"+(str3.equals(str4)));//true
System.out.println(str5.equals(str6));//true
System.out.println(str5==str6);//false
| 类型 | 相同对象范围 | 不同对象范围 |
|---|---|---|
| Integer | (-128,128) | i>=128||i<-128 |
| Short | (-128,128) | s>=128||s<=-128 |
| Character | c<128 | c>=128 |
| Long | (-128,128) | v>=128||v<-128 |
一个归类:
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。



