JAVA研发工程师面试重点(语法基础篇1)

  • 一、JAVA基础知识(1)
  • 1、内部类
  • 1.1 内部类的优缺点
  • 内部类的优点:
  • 内部类的缺点:
  • 1.2 内部类的分类
  • A、普通内部类
  • B、静态内部类
  • C、匿名内部类
  • D、局部内部类
  • 1.3、内部类与外部类的关系
  • 1.4、内部类的使用场景和好处
  • 2、final
  • 2.1、修饰类
  • 2.2、修饰方法
  • 2.3、声明常量
  • 2.4、final关键字的好处
  • 2.5、final总结


一、JAVA基础知识(1)

1、内部类

1.1 内部类的优缺点

内部类的优点:

  1. 内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)。
  2. 内部类是另外一种封装,对外部的其他类隐藏。
  3. 内部类可以实现java的单继承局限。

内部类的缺点:

结构复杂。

1.2 内部类的分类

在Java中内部类主要分为

A、普通内部类

  1. 普通内部类内部不允许存在任何static变量或方法 正如成员方法中不能有任何静态属性 (成员方法与对象相关、静态属性与类有关)
  2. 普通内部类是依附外部类的,只有创建了外部类才能创建内部类。
    例子:在创建一个普通内部类对象时首先需要创建其外部类对象,内部类就像外部类声明的一个属性字段一样,因此其的对象时依附于外部类对象而存在的。
public class TestClass {

    public class TestClassA {
        
    }
}

B、静态内部类

关键字static可以修饰成员变量、方法、代码块、其实还可以修饰内部类,使用static修饰的内部类我们称之为静态内部类,静态内部类和非静态内部类之间存在一个最大的区别,非静态内部类在编译完成之后会隐含的保存着一个引用,该引用是指向创建它的外围类,但是静态类没有。没有这个引用就意味着:

  1. 静态内部类的创建不需要依赖外部类可以直接创建。
  2. 静态内部类不可以使用任何外部类的非static类(包括属性和方法),但可以存在自己的成员变量。

一个类的静态成员独立于这个类的任何一个对象存在,只要在具有访问权限的地方,我们就可以通过 类名.静态成员名 的形式来访问这个静态成员,同样的,静态内部类也是作为一个外部类的静态成员而存在,创建一个类的静态内部类对象不需要依赖其外部类对象。

class Outer {
    public String name = "test";
    private static int age =20;

    static class Inner{
        private String name;
        public void fun()
        {
            System.out.println(name);
            System.out.println(age);
        }
    }
}
public class Test{
    public static void main(String [] args)
    {
        Outer.Inner in = new Outer.Inner();
    }
}

C、匿名内部类

匿名内部类没有类名,因此没有构造方法。
匿名内部类就是一个没有名字的方法内部类,因此特点和方法与方法内部类完全一致,除此之外,还有自己的特点:

  1. 匿名内部类必须继承一个抽象类或者实现一个接口。
  2. 匿名内部类没有类名,因此没有构造方法。

匿名内部类有多种形式,其中最常见的一种形式莫过于在方法参数中新建一个接口对象 / 类对象,并且实现这个接口声明 / 类中原有的方法了

//匿名内部类
//声明一个接口
interface MyInterface {
    //接口中方法没有方法体
    void test();
}
class Outer{
    private int num = 5;
    public void dispaly(int temp)
    {
        //匿名内部类,匿名的实现了MyInterface接口
        //隐藏的class声明
        new MyInterface()
        {
            public void test()
            {
                System.out.println("匿名实现MyInterface接口");
                System.out.println(temp);
            }
        }.test();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly(3);
    }
}

D、局部内部类

局部内部类顾名思义就是定义在方法里的类

  1. 方法内部类不允许使用访问权限修饰符(public、private、protected)均不允许。
  2. 方法内部类对外部完全隐藏,除了创建这个类的方法可以访问它以外,其他地方均不能访问 (换句话说其他方法或者类都不知道有这个类的存在)方法内部类对外部完全隐藏,出了创建这个类的方法可以访问它,其他地方均不能访问。
  3. 方法内部类如果想要使用方法形参,该形参必须使用final声明(JDK8形参变为隐式final声明)

局部内部类使用的比较少,其声明在一个方法体 / 一段代码块的内部,而且不在定义类的定义域之内便无法使用,其提供的功能使用匿名内部类都可以实现,而本身匿名内部类可以写得比它更简洁,因此局部内部类用的比较少。

class Outer{
    private int num =5;
    //普通方法
    public void dispaly(int temp)
    {
        //方法内部类即嵌套在方法里面
        class Inner{
            public void fun()
            {
                System.out.println(num);
                temp++;
                System.out.println(temp);
            }
        }
        //方法内部类在方法里面创建
        new Inner().fun();
    }
}
public class Test{
    public static void main(String[] args)
    {
        Outer out = new Outer();
        out.dispaly(2);
    }
}

1.3、内部类与外部类的关系

  1. 对于非静态的内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。
  2. 内部类可以直接访问外部类的元素(包括私有域)—外部类在内部类之前创建,创建内部类时会将外部类的对象传入**
  3. 外部类可以通过内部类的引用间接访问内部类元素 – -要想访问内部类属性,必须先创建内部类对象**
  4. 内部类是一个相对独立的个体,与外部类没有关系。

1.4、内部类的使用场景和好处

  1. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,
  2. 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
  3. 方便编写事件驱动程序
  4. 方便编写线程代码

2、final

凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量。final变量经常和static关键字一起使用,作为常量。

final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

2.1、修饰类

使用final来修饰的类叫作final类。final类通常功能是完整的,它们不能被继承。Java中有许多类是final的,譬如String, Interger以及其他包装类。

final class Eunuch{//
	
}
class Son extends Eunuch{//错误
	
}

2.2、修饰方法

final也可以声明方法。方法前面加上final关键字,代表这个方法不可以被子类的方法重写。如果你认为一个方法的功能已经足够完整了,子类中不需要改变的话,你可以声明此方法为final。final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。表示这个方法不能被子类重写,但是子类仍能访问

class Father{
	public final void method(){
		System.out.println("father");
	}
}
class Son extends Father{
	public void method(){//错误
		System.out.println("son");
	}
}

2.3、声明常量

final修饰某个变量(成员变量或局部变量),表示它的值就不能被修改,即常量,常量名建议使用大写字母。

如果某个成员变量用final修饰后,没有set方法,并且必须初始化(可以显式赋值、或在初始化块赋值、实例变量还可以在构造器中赋值)

public class Test{
    public static void main(String[] args){
    	final int MIN_SCORE = 0;
    	final int MAX_SCORE = 100;
    }
}
class Chinese{
	public static final String COUNTRY = "中华人民共和国";	
	private String name;
	public Chinese( String name) {
		super();
		this.name = name;
	}
	public Chinese() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	//final修饰的没有set方法
	public static String getCountry() {
		return COUNTRY;
	}
}

2.4、final关键字的好处

  1. final关键字提高了性能。JVM和Java应用都会缓存final变量。
  2. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。
  3. 使用final关键字,JVM会对方法、变量及类进行优化。

2.5、final总结

  1. final关键字可以用于成员变量、本地变量、方法以及类。
  2. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
  3. 你不能够对final变量再次赋值。
  4. 本地变量必须在声明时赋值。
  5. 在匿名类中所有变量都必须是final变量。
  6. final方法不能被重写。
  7. final类不能被继承。
  8. final关键字不同于finally关键字,后者用于异常处理。
  9. final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。
  10. 接口中声明的所有变量本身是final的。
  11. final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
  12. final方法在编译阶段绑定,称为静态绑定(static binding)。
  13. 没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。
  14. 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
  15. 按照Java代码惯例,final变量就是常量,而且通常常量名要大写: