Java初级知识学习

 

01-04

1、安装Java环境,跑通一个输出hello world的程序

 

2、下面的代码执行后,i和j分别是多少?int i = 0;int j = i++;int k = --i。

执行后i和j都是0;

第一个j=i++;++在后面先用再执行,所以j是0,i变成1

第二个k= --i;--在前面,先执行再用,所以i变成0,然后再是k=i;所以k和i都是0

3、Java中&与&&的区别是什么?

一个&的且,比较时左右两边的都会执行,左右不是布尔型时是与运算符

两个的&&且,短路运算符,如果左边为假,右边的就不用执行了,只有左边为真时才会执行右边

例1:

int i = 0,j=1;
if(i==1&&j--==1){}
System.out.println(j);
if(i==1&j--==1){}
System.out.println(j);

 

 

两个条件结果都是false,但是j值,两个的&&后会输出1,一个的&后的输出0,想总是执行后面的j–就要用一个&

例2:

String str=null;

if(str!=null&!str.equals("")){}  //会报错
if(str!=null&&!str.equals("")){}  //不报错

这种右边的条件要依赖左边的条件为真时,就一定要用&&,否则程序直接报空指针异常了

 

4、Java中break和continue的用法及区别?

break和continue都可以用作结束循环,break结束整个循环,continue只是结束本次循环

例:

int i=0;
while(i++<10){
    if(i==3){
        continue;
    }
    if(i==6){
        break;
    }
    System.out.println(i);
}

 

 

输出:1 2 3 5,第一次走到i==3时因为是continue,所以只结束了这次循环,所以只是不输出3  直接到i=4,后面的4 5就正常输出,第二次走到i==6时,执行brak所以整个while就结束了

break和continue默认结束本次的整个循环,特殊标识的还会结束掉标识所在下面的全部循环,标识用 名称+:标识,用的很少,表示我没有用过

例:

name:  //标识
for(int j=0;j<10;j++){
int i=0;
while(i++<10){
    if(i==3){
        break name; //使用标识
    }
    System.out.println(i);
  }
}

 

 

break后面加上标识,就会结束标识下面的全部循环,也就是到了i==3后,不光while循环结束,for循环也会结束,只会输出1 2

continue+标识,也是会结束外面for的本次循环,所以会输出很多个  1  2

 

5、JDK和JRE的区别是什么?

jre是Java的运行时环境,包括了Java虚拟机,基础类库等,就是编写好的Java程序运行的地方

jdk是Java开发的工具包,jdk包含了jre,多了一些调试工具,javac编译程序等,要开发一般都用的是jdk,jdk就是开发环境+运行环境,而jre只有运行环境

-Q5:Java支持的数据类型有哪些?什么是自动拆装箱?并请编写代码Demo说明。

Java有8种基本数据类型

整数类型byteshortintlong 

浮点数类型floatdouble

字符类型char   

布尔类型boolean

自动拆装箱,对应的包装器类型Byte,Short,Integer,Long,Float,Double,Character,Boolean

装箱就是  基本类型——》包装器类型  int类型转到Integer类型,借助的是 int a=1; a = Integer.valueOf(a)

拆箱就是  包装器类型——》基本类型  Integer转到int 等于 Integer a=new Integer(1);  a= a.IntValueOf(a);

自动拆装箱就是自动执行了上面的内容,Integer a=1;就直接把int类型的1变成了Integer类型,if(a<2)就直接把Integer类型的a变成了int类型的a

05-10

1、静态内部类与非静态内部类的区别是什么?

非静态内部类可以使用外部类的所有变量和方法,静态的和非静态的都可以使用,但是本身内部的类不能有静态的属性,静态变量和方法都不能有

静态内部类,内部本身可以声明静态变量和方法,也可以声明非静态的,但是调用只能调用外部类的静态变量和方法,不能调用非静态的东西;因为加载时 所有静态的会在非静态前加载,如果静态中调用了非静态的方法,该方法的对象就还没有创建,会有错误就不被允许。

2、创建啮齿动物(Rodent):老鼠(Mouse)、鼹鼠(Gerbil)、大颊鼠(Hamster)这样一个继承结构,在基类中提供通用的方法,并在子类中根据特定的Rodent类型覆盖这些方法,以便执行不同的行为,创建一个Rodent数组并填充不同的Rodent类型,执行基类的方法,观察结果。

例:

public abstract class Rodent {
	public abstract void say();
}

public class Gerbil extends Rodent{


	@Override
	public void say() {
		System.out.println("我是鼬鼠!");
	}


}


public class Hamster  extends Rodent{


	@Override
	public void say() {
		System.out.println("我是大颊鼠!");
	}


}


public class Mouse  extends Rodent{


	@Override
	public void say() {
		System.out.println("我是老鼠!");
	}

}


public class Main {


	public static void main(String[] args) {
		Rodent []r =new Rodent[3];
		r[0]= new Mouse();
		r[1]= new Gerbil();
		r[2]= new Hamster();
		
		for(int i=0;i<r.length;i++) {
			r[i].say(); //都是执行say方法,因为继承后被重写,所以输出不同的行为
		}
	}
}

结果:
我是老鼠!
我是鼬鼠!
我是大颊鼠!


 

3、编写一个程序,验证(静态变量、静态初始化块、变量、初始化块、构造器)的初始化顺序。

例子:

public class StaticTest {
public StaticTest() {
System.out.println("构造器中的b:"+b);
System.out.println("构造器中的c:"+c);
System.out.println("构造器中的d:"+d);
System.out.println("构造器");
}
static int a=123;
int b=233;
static {
System.out.println("静态块中的静态a:"+a);
// System.out.println("静态块中的静态c:"+c);  //报错
System.out.println("静态块");
}
{
System.out.println("普通块中的变量b:"+this.b);
System.out.println("普通块中的静态c:"+c);
System.out.println("普通块中的变量d:"+this.d);
System.out.println("普通块");
}
static int c=444;
int d=555;
public static void main(String[] args) {
      new StaticTest();
}

 

输出:

静态块中的静态a:123
静态块
普通块中的变量b:233
普通块中的静态c:444
普通块中的变量d:0
普通块
构造器中的b:233
构造器中的c:444
构造器中的d:555
构造器

结论,由上面结果可以看出,初始化时,会先初始化静态的变量和块,静态块中输出a有值说明静态变量a比静态块先初始化,但是静态变量c显示报错此时还没有初始化,所以得出结论

静态块和静态变量 > 普通块和变量 > 构造器,同级别时,初始化就按照代码里面的出现顺序计算,静态块前面的静态变量就能正常输出,后面的就无法输出报错

4、请写出作用域public、private、protected及其区别?并请编写代码Demo说明。

4.1 public 公开的: 可以访问的范围最大,当前类,子类,外部类,其他类,不在同一个包的类只要import引入了  都可以访问public 修饰的方法或者变量

4.2 private 私有的:只能由当前类访问;其他子类,外部类都不能访问,其他类想访问该私有方法或者变量,只能通过该类另一个公开的方法间接访问

4.3  protected 受保护的: 同一个包内的都可以访问,当前类,子类,同一个包的其他类,一般继承时使用较多

4.4 不写时默认为default : 当前类和同一个包的其他类能访问,子类,其他包的类不能访问

例子:

//父类

package com.testb;  
public abstract  class PublicClassTest {
public void A() {
System.out.println("public A");
}
private void B() {
System.out.println("public B");
}
protected void C() {
System.out.println("public C");
}
}


//子类

package com.testb;
public class OtherClassTest extends PublicClassTest{
public void D() {
System.out.println("public D");
}
private void E() {
System.out.println("public E");
}
protected void F() {
System.out.println("public F");
}
public static void main(String[] args) {
new OtherClassTest().D(); //public能访问当前类
new OtherClassTest().A(); //子类可以访问父类的public方法


new OtherClassTest().B(); // private 子类访问报错
new OtherClassTest().E(); //  当前类可以访问private


new OtherClassTest().C(); // protected 能访问当前类
new OtherClassTest().F(); //  当前类可以访问protrcted
}
}
//其他包的类
package com.test;
import com.testb.OtherClassTest;
public class Test {
public void Other() {
    new OtherClassTest().A(); //不同包的其他类可以访问public
    new OtherClassTest().B(); //外部类访问private 报错
    new OtherClassTest().C(); // 外部类访问protected报错
}
}

 

5、请问Java中接口与抽象类的区别是什么?应该如何从二者中做选择?请编写代码Demo说明。

接口内只能定义功能,所有属性都是public static final 修饰,所有方法都是抽象的,但是接口可以实现多个;抽象类的方法可以是抽象的也可以是非抽象的,但是继承只能继承一个

抽象类例子:

package com.test.c;
public abstract class Animal1 {
int year =100;
public abstract void eat();
public void play() {
System.out.println("动物都会玩!");
}
}
package com.test.c;
public class Pelope1 extends Animal1{
@Override
public void eat() {
System.out.println("动物会吃!");
}
public static void main(String[] args) {
new Pelope1().play();
new Pelope1().eat();
System.out.println(new  Pelope1().year);
}
}

 

//抽象类可以定义抽象的eat方法,也可以定义已经有具体功能的方法play,子类Pelope1继承该类后,必须实现抽象的eat方法,重写赋予具体功能,而已经有具体功能的play方法,子类就可以选择直接调用或者重写

但是缺点就是只能继承一个抽象类,再来一个抽象类,两个就没发继承了

选择:一般不光属性和方法抽象,部分功能也有逻辑关系这种的就可以选择抽象类,里面可以定义一些只有相同属性的抽象方法,也可以将通用功能的实现放在里面,子类就不用再重写直接使用

 

//接口例子:
package com.test.c;
public interface Animal2 {
public static final int year = 100;
public  void eat();
}


package com.test.c;
public interface Animal3 {
public  void sleep();
}


package com.test.c;
public class Pelope2 implements Animal2,Animal3{
public static void main(String[] args) {
Pelope2 p = new Pelope2();
p.eat();
p.sleep();
System.out.println(p.year);
}
@Override
public void eat() {
System.out.println("动物会吃!");
}
@Override
public void sleep() {
System.out.println("动物会睡觉!");
}
}

 

//Animal2和Animal3都是两个接口,定义了两个抽象的方法eat和sleep,Pelope2可以继承Animal2实现eat方法,也可以继承Animal3实现play方法;也可以同时继承Animal2和Animal3同时实现两个方法

选择:一般只有属性和方法相同,子类可能没有什么逻辑关系,或者只有很少一部分功能重合 的时候应该使用接口,子类继承后都需要重写,因为接口可以多继承,要多继承时只能选择接口,目前只需要单继承,通用方法不是太多时也应该选择接口,为后面维护可能出现多继承提供方便

 

 

6、请问 final, finally, finalize的区别?请编写代码Demo说明。

6.1 final:可以修饰类方法和变量,修饰类,这个类就不能被继承,不能有子类;修饰方法,这个方法可以被继承但是不能被重写;修饰变量表示赋值一次后值就不允许被修改了

6.2 finally:异常处理的一部分,try  catch finally ,表示不管是否异常 都一定执行,一般释放资源使用

6.3  finalize: 是在java.lang.Object里面定义的,每个对象都有这个方法,方法在gc启动,回收时调用,只会调用一次,super.finalize()意思是调用回收这个对象,但是执行后不是立马就把对象回收了,排队的时候这个对象如果又不需要被回收,然后再次真正要回收时,因为这个方法只能被调用一次,所以就会产生问题,因此一般很少自己写super.finalize()回收对象,写了就要考虑未被回收的情况要再次手动回收

 

例1:
public final class FinalClass {
}
public class SonClass extends FinalClass { //报错,因为final修饰的类不能被继承,只能当作子类
}
例2:
public abstract class FinalClass2  {
public final void A() {
}
public void B() {
}
}
public class SonClass extends FinalClass2 {
// @Override
// public void A() { //报错,final修饰的方法,可以继承下来直接使用,但是不能被重写,表示最终的方法
// }
@Override
public void B() {
}
public static void main(String[] args) {
new SonClass().A(); //不能重写,但是可以直接使用
final int i=1;
// i=2;
System.out.println(i);
}
}
例3:
public static int A(int a) throws Exception {
int b=1;
try {
b/=a;
}catch(Exception e){
return 0;
}
finally {
B();// 表示不管是否异常,一定会调用B方法,try catch 前还有其他异常原因除外
}
return b;
}
public static void B() {}

 

 

7、请问 overload和override的区别?overload的方法是否可以改变返回值的类型?

overload是重载,是一个类中的多态表现,方法名一样,不同的参数类型,参数个数,不同参数类型的顺序不同都可以实现重载,主要是跟参数有关,和返回值无关,调用同一个方法名,传的参数不一样就会自动调用相应方法,就叫重载。方法名一样只和参数有关,所以可以改变返回值

例:

public static int a(int x){
    return x;
)
public static String a(String x){
    return x;
)
int i=0;
String j="sss";
a(i);  //检测到i是int类型就会调用第一个方法
a(j);  //检测到j是String就会调用第二个方法,而且可以很容易看出overload是可以改变返回值的






override是重写,是父类与子类之间的多态表现,就是子类覆盖了父类中的方法,实现接口和抽象类中的方法就是一种重写,和重载不同的是,重写就必须要返回值类型和参数必须一摸一样才能实现重写,包括异常子类重写也要抛出和父类一样或者也是父类异常的子类;并且覆盖的方法不能是private私有的,私有方法不能被继承,所以子类就算实现了完全一样的一个方法,也只是重新写了一个新的方法,没有对其进行覆盖。

例:

public class A {
	public void a() {
		System.out.println("AAA");
	}
	private void b() {
		System.out.println("BBB");
	}
	public A() {
		a();
		b();
	}
}
public class B extends A{
	
	public void a() {
		System.out.println("aaaa");
	}
	public void b() {
		System.out.println("bbbb");
	}


	public static void main(String[] args) {
		B b=new B();
		b.a();
		b.b();
	}
}


结果:
aaaa  //首先调用构造函数的a方法,因为a方法已经被重写,所以输出的是重写后的内容
BBB   //再调用构造函数的b方法,因为b方法是私有的不能被重写,所以访问的还是父类A原有的b方法
aaaa  //调用子类重写后的a方法
bbbb  //只是调用了子类新写的一个名字一样的b方法,和父类的b方法无关


11-14

1、请写一个程序模拟几种常见的Exception,如果catch与try块中有return语句,finally块还会执行吗?

catch与try块中有return语句,finally块还会执行,且必须是这个try catch 中的return才会执行,之前有return的话,就会因为根本走不到这个块,所以不会执行,finally常用于一些资源关闭使用。

例:

public class TryCatch {
	public static int a(int i) {
		
		int j=3;
		int [] a=new int[2];
		try {
			j= 1/i;    //ArithmeticException,算数运算异常,1/0这种
			j=a[2];    //NullPointerException 空指针异常
			new FileInputStream("d");  //FileNotFoundException找不到文件异常
			return j;
		}catch(Exception e) {  //上面异常都属于Exception的子类
			System.out.println("异常抛出!");
			return 0;
		}
		finally
		{
			System.out.println("finally块!");
		}
	}
	public static void main(String[] args)  {
		System.out.println(a(1));
	}
}
结果:
异常抛出!
finally块!
0

 

2、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

2.1  try:里面一般放可能出问题的正常业务代码,意思就是监控这部分代码是否有异常,无异常就正常执行,有异常就会被后面的catch块捕获。

2.2  catch:捕获异常的块,try块里有问题的对象,就会被对应的catch捕获,从而进行相应的处理,一般可能会在catch块里面打日志记录下原因,然后给一个异常情况的返回。

2.3  finally: 一般放在 catch 后面,表示异常流程一定要执行的代码块,一般用于一些必要的资源释放什么的。

2.4 :throw :手动抛出异常,自己判断异常情况,然后给个类似throw new Exception(); 这种的异常抛出。

2.5: throws: 声明抛出的异常,一般放在方法名后面,声明一下这个方法可能出现的异常,可以声明一个,也可以是多个

2.6: try块中可以抛出异常,比如说手动抛出,在try块中手动throw new Exception();  也会被catch捕获。

 

3、请问Java匿名内部类怎样创建?有什么作用和优点?请编写代码Demo说明。

例:

public interface C {
	public void c1();
}
public class B {
	public void a() {
		new C() {  //创建匿名内部类,C是一个接口,本来应该是要有个类继承C接口,然后实现c1方法,匿名内部类就省略了这个类,直接可以调用该方法
			public void c1() {
				System.out.println("c1");
			}
		}.c1(); //直接调用重写后的c1方法
	}
	public static void main(String[] args) {
		new B().a();
	}
}

匿名内部类,作用和优点就是,主要是针对某些只想用某个类或者某个接口的一个方法时,就可以省略继承这个类或接口,直接使用匿名类继承然后重写方法,去直接实现该方法的调用。可以使代码更简介,不用再多写一个类。

4、请解释Java中List、Set和Map的区别和应用场景?

List,Set都是继承自Collection接口,都是单个的元素,而map是键值对的数据,所以List和Set是一大类,map是另一类

List:是有顺序的,可以重复,例如ArrayList,可以通过下标找到元素,就能用for循环遍历下标找到所有元素,也可以用迭代器遍历,顺序结构所以查找非常方便,根据大小就可以查找出位置,但是插入和删除效率就非常低,比如插入一个最小值,那后面所有的元素都得动。

Set :是无序的,不能重复,每个值都有他的固定位置,例如HashSet就是通过哈希值确定位置,链表式结构,无法使用下标找值,只能用迭代器,但是因为值的位置固定,所以插入和删除效率很高,都是只需要计算就可以知道插入到哪,删除哪里,其他元素不受影响。

Map:是键值对形式,键唯一,通过键可以找到对应的值

应用场景:

频繁查找就用List(适用于,插入一次后,后面基本都是用于搜索的数据,顺序排列后,利用二分查找等效率就会很高);频繁插入和删除就用Set(更新较多的数据就比较适合用Set,插入不需要重新排序);需要键值对形式的,就用Map(key value形式的数据,比如映射这种)

5、String类的==与equals区别是什么?StringBuffer与StringBuilder的区别是什么?如何选用?

==比较的是地址值,判断是不是一个地址,equals比较的是该地址对应内容的值

public static void d() {
		String s1="aaa";
		String s2="aaa";
		String s3=new String("aaa");
		
		System.out.println(s1==s2); //true s1和s2是同一个地址,所以==是true
		System.out.println(s1==s3);  //s3因为强行new了一个新地址,所以地址肯定发生变化,返回false
		
		System.out.println(s1.equals(s2));  //equals比较的是地址对应值的内容,所以三个都是String类型的aaa所以都返回true
		System.out.println(s1.equals(s3));
	}

 

StringBuffer和StringBuilder 好处都是对象可以多次被修改(String类型的对象创建成功后不能被修改,平时使用看着可以修改,是因为又new了一个新对象,再把变量指到新的),不产生新的未使用对象,StringBuilder效率更高速度更快,多数情况使用StringBuilder;只用有线程安全要求时使用StringBuffer

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值