java面试题-Java基础部分-基础语法 11-20

本文深入解析Java基础语法,涵盖==与equals的区别、静态变量与实例变量的不同、static方法调用规则、Integer与int的差异、Math.round方法的使用、代码常见错误、访问修饰符的作用域、Overload与Override的概念、构造器的特性以及接口和抽象类的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础语法 11-20

11、"=="和equals方法究竟有什么区别?

12 、静态变量和实例变量的区别?

13 、是否可以从一个 static  方法内部发出对非 static  方法的调用?

14 、Integer 与 与 int  的区别

15 、Math.round(11.5) 等於多少? Math.round(-11.5) 等於多少?

16 、下面的代码有什么不妥之处?

17 、请说出作用域 public ,private ,protected ,以及不写时的区别

18、Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值 的类型? 

19、构造器 Constructor 是否可被 override? 

20、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可 继承具体类(concrete class)?抽象类中是否可以有静态的 main方法? 


11、"=="和equals方法究竟有什么区别?

单独把一个东西说清楚,然后再说清楚另一个,这样,它们的区别自然就出来了,混在一起说,则很难说清楚

==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。

如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。

equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。

public class TestMain {
	public static void main(String[] args) {
		comparation01();
	}

	public static void comparation01() {
		byte b1 = 4, b2 = 4;
		char c1 = '你', c2 = '你';
		double d1 = 4.0, d2 = 4.0;
		long lg1 = 100, lg2 = 200;
		boolean b3 = true, b4 = true;
		if (b1 == b2) {
			System.out.println("==比较俩基本型:byte型的值相同");
		}
		if (c1 == c2) {
			System.out.println("==比较俩基本型:char型的值相同");
		}
		if (d1 == d2) {
			System.out.println("==比较俩基本型:double型的值相同");
		}
		if (b1 == b2) {
			System.out.println("==比较俩基本型:byte型的值相同");
		}
		if (b3 == b4) {
			System.out.println("==比较俩基本型:boolean型的值相同");
		}
		if (lg1 != lg2) {
			System.out.println("==比较俩基本型:两个long型的值不同!");
		}
		String s1 = "写作业呢", s2 = "写作业呢";// 位于方法区中的常量池,常量就意味着只有一个对象
		String s5 = new String(), s6 = new String(), s7 = s6;
		if (s1 == s2) {
			System.out.println("String引用型s1==s2比较俩对象地址的结果:是同一个对象(常量)");
		}

		Integer itg3 = new Integer("10"), itg4 = new Integer("10");
		if (itg3 != itg4) {
			System.out.println("==结果: 引用型itg3=new Integer(10)和itg4=new Integer(10)不是同一个对象(堆内存地址)!");
		}
		if (itg3.equals(itg4)) {
			System.out.println("Integer引用类型的itg3.equals(itg4)比较的是值:结果为true");
		}
		if (s5.equals(s6)) {
			System.out.println("String型重写了equals(), 比较俩值结果:是相同的");
		}
		if (s6 == s7) {
			System.out.println("String引用型s6=new String(), s7=s6,==比较的结果:是同一个对象");
		}
	}

	public static void comparation02() {
		int a1 = 1;
		int a2 = 1;
		Integer b1 = new Integer(1);
		Integer b2 = new Integer(1);
		// 基本型的==比较的是值而不是对象
		System.out.println("int a1=1; int a2=1; a1==a2:\t" + (a1 == a2));
		// 比的是对象(内存地址)
		System.out.println("Integer b1 =new Integer (1); Integer b2 =new Integer (1); b1==b2:\t" + (b1 == b2));
		// 俩对象地址不同 。但是Integer已重写equals, 比较的是内容:相同
		System.out.println("Integer b1 =new Integer (1); Integer b2 =new Integer (1); bi.equals(b2):\t" + (b1.equals(b2)));
	}

}

示例来源于:https://blog.youkuaiyun.com/qq_31598113/article/details/53995957

执行结果:

==比较俩基本型:byte型的值相同
==比较俩基本型:char型的值相同
==比较俩基本型:double型的值相同
==比较俩基本型:byte型的值相同
==比较俩基本型:boolean型的值相同
==比较俩基本型:两个long型的值不同!
String引用型s1==s2比较俩对象地址的结果:是同一个对象(常量)
==结果: 引用型itg3=new Integer(10)和itg4=new Integer(10)不是同一个对象(堆内存地址)!
Integer引用类型的itg3.equals(itg4)比较的是值:结果为true
String型重写了equals(), 比较俩值结果:是相同的
String引用型s6=new String(), s7=s6,==比较的结果:是同一个对象

 

12 、静态变量和实例变量的区别?


在语法定义上的区别:

  1. 静态变量前要加 static 关键字,又称全局变量,属于类所有。(static修饰方法为类方法,修饰一段代码为静态代码块)
  2. 实例变量前则不加。属于类对象所有。

在程序运行时的区别:

  1. 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。
  2. 静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。

 

总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。
例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个 staticVar 变量,并且每创建一个实例对象,这个 staticVar 就会加1;但是,每创建一个实例对象,就会分配一个 instanceVar,即可能分配多个 instanceVar,并且每个 instanceVar 的值都只自加了1次。

public class VariantTest{
    public static int staticVar = 0;
    public int instanceVar = 0;
    public VariantTest(){
        staticVar++;
        instanceVar++;
        System.out.println(“staticVar=” + staticVar + ”,instanceVar=”+instanceVar);
    }
}

备注:这个解答除了说清楚两者的区别外,最后还用一个具体的应用例子来说明两者的差异,体现了自己有很好的解说问题和设计案例的能力,思维敏捷,超过一般程序员,有写作能力!

13 、是否可以从一个 static  方法内部发出对非 static  方法的调用?


不可以。因为非 static 方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而 static 方法调用时不需要创建对象,可以直接调用。也就是说,当一个 static 方法被调用时,可能还没有创建任何实例对象,如果从一个 static 方法中发出对非static 方法的调用,那个非 static 方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个 static 方法内部发出对非 static 方法的调用。

 

14 、Integer 与 与 int  的区别


int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为 int 提供的封装类。int 的默认值为0,而 Integer 的默认值为 null,即 Integer 可以区分出未赋值和值为0的区别,int 则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用 Integer。

在 JSP 开发中,Integer 的默认为 null,所以用el 表达式在文本框中显示时,值为空白字符串,而 int 默认的默认值为0,所以用 el 表达式在文本框中显示时,结果为0,所以,int 不适合作为 web 层的表单数据的类型。


在 Hibernate 中,如果将 OID 定义为 Integer 类型,那么 Hibernate 就可以根据其值是否为null 而判断一个对象是否是临时的,如果将 OID 定义为了 int 类型,还需要在 hbm 映射文件中设置其 unsaved-value 属性为0。

另外,Integer 提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。

 

15 、Math.round(11.5) 等於多少? Math.round(-11.5) 等於多少?


Math 类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英
文名称的含义相对应,

例如,ceil 的英文意义是天花板,该方法就表示向上取整,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;

floor 的英文意义是地板,该方法就表示向下取整,Math.ceil(11.6)的结果为11,Math.ceil(-11.6)的结果是-12;

最难掌握的是round 方法,它表示“四舍五入”,算法为 Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。


16 、下面的代码有什么不妥之处?

if(username.equals(“zxx”){}


int x = 1;
return x==1?true:false; 
  1. username 可能为 NULL,会报空指针错误;改为"zxx".equals(username)
  2. return后面改成 return x==1;就可以!

17 、请说出作用域 public ,private ,protected ,以及不写时的区别


这四个作用域的可见范围如下表所示。
说明:如果在修饰的元素上面没有写任何访问修饰符,则表示 friendly。

备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上
分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。

18、Overload 和 Override 的区别。Overloaded 的方法是否可以改变返回值 的类型? 


Overload:重载。Override :重写。 两者都是java多态的表现形式。

重载 Overload :同一个类中 多个方法 名称相同,但参数列表各不相 同(即参数个数或类型不同)。

重写 Override :子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子 类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不 能更小。

如果父类的方法是 private 类型,那么,子类则不存在覆盖的限制,相当于子类中 增加了一个全新的方法。

 

至于 Overloaded 的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这 个题目很模糊。如果几个Overloaded 的方法的参数列表不一样,它们的返回者类型当然也 可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它 们的返回值不同来实现重载 Overload。这是不行的,

我们可以用反证法来说明这个问题, 因为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如, 我们调用 map.remove(key)方法时,虽然 remove 方法有返回值,但是我们通常都不会定义 接收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返 回类型不同,java 就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果 类型来判断。  

override 可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达 到不同的作用。对我们来说最熟悉的覆盖就是对接口方法的实现,在接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。

除了这个典型的用法以外, 我们在继承中也可能会在子类覆盖父类中的方法。

在覆盖要注意以下的几点:

  1. 覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
  2. 覆盖的方法的返回值必须和被覆盖的方法的返回一致;
  3. 覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
  4. 被覆盖的方法不能为 private,否则在其子类中只是新定义了一个方法,并没有对其进行 覆盖。

overload 对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同 的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:

  1. 在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不 同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是 fun(int,float), 但是不能为 fun(int,int));
  2. 不能通过访问权限、返回类型、抛出的异常进行重载;
  3. 方法的异常类型和数目不会对重载造成影响;
  4. 对于继承来说,如果某一方法在父类中是访问权限是 priavte,那么就不能在子类对其进 行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。

19、构造器 Constructor 是否可被 override? 

构造器 Constructor
不能被继承,因此不能重写 Override ,但可以被重载 Overload 。
 

20、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可 继承具体类(concrete class)?抽象类中是否可以有静态的 main方法? 


接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中 可以有静态的 main 方法

备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是 java 语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道 理不提供,那答案就是肯定的了。  只有记住抽象类与普通类的唯一区别:就是不能创建实例对象和允许有 abstract 方法。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EngineerForSoul

你的鼓励是我孜孜不倦的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值