A、编译器会先查看对象的类型与方法名;假设调用e1.find(param),编译器会查找e1类名为find的方法(可能存在多个,比如find(String str)、find(int a)等),以及e1父类中访问属性为public且名字为find的方法(即继承的方法也会被找到);
至此,编译已经获得了所有可能被调用的“候选”方法。
B、接下来,编译器查看参数的调用类型;所有为find的方法中与提供的参数类型完全匹配的,就选择执行这个方法;这个过程被称为重载解析(overloading resolution)。
这个过程对编译器来说会比想象中的复杂,因为可能存在类型转换,比如int可以转换为String,Manger可以被转换为Employee;最终如果编译器没有找到参数类型匹配的方法,或者经过类型转换以后有多个方法匹配,就会报告一个错误;
此致,编译已经获得了需要的方法名字和参数类型。
6、动态绑定与静态绑定;
A、以上这些查找方法的过程,就是动态绑定;即在执行之前编译器并不确定要执行哪个方法,通过一系列分析才确定。
D、静态绑定:如果是private方法、static方法、final方法或者构造器,那么编译器可以准确的知道应该调用哪个方法,这种调用方式成为静态绑定(static binding)。
C、上文中动态绑定搜索方法的过程明显效率低下,时间开销较大,因此虚拟机就预先为每个类创建了一个方法表(method table),每次搜索直接查找这个表就可以了;另外对于super修饰的方法,编译器会直接去查找超类。
7、阻止集成:final类和方法
A、有时候希望阻止利用某个类定义子类,这种不允许扩展的类利用final修饰,被称为final类。
B、利用final修饰的类,所有方法自动成为final方法,但是类的域并不是final类型的(即属性并不是final的)。
C、定义为final的目的主要是为了确保他们不会在子类中改变语义。String就是一个final类,因此一个String对象必定是String型的,不存在多态导致是其他类型。
8、抽象类(abstract class)
A、用abstract修饰的类被称为抽象类,抽象类可以理解为是占位符,提供一些通用的但是又暂时不想实现的方法;
B、抽象方法中除抽象方法外,还可以包含具体的数据和具体的方法;
C、抽象类的实现子类中,如果全部实现了抽象方法,那么这个类就不再是抽象类;子类实现部分抽象方法或者完全不实现抽象类的方法,这样子类也必须标记为抽象类;
D、类即使不包含抽象方法也是可以声明为抽象类的;
F、抽象类不能被实例化,但是抽象类可以利用子类(子类不是抽象类)来实例化。
9、类的保护(protected),private谁也无法访问,而public又谁都可以访问不安全,因此可以用protected来修饰;protected修饰的属性或者方法可以被继承,在同一个包内可以被访问。
10、Object类:所有类的超类
equals方法,它用于检测一个对象是否等于另外一个对象,在Object类中,这个方法判断对象是否具有相同的引用;然而在现实中这种比较意义不大,现实中比较的是两个对象的状态是否相等;
比如:两个Employee比较,对比的是他们的name、address、solary这些是否相等;而并不会去比较两个employee是否指向的是同一个对象的引用。
11、泛型数组列表
A、ArrayList数组,eg:ArrayList staff=new ArrayList();//第二个Employee可以省略,即new ArrayList<>();
B、数组的长度确定以后想改变非常费事,而ArrayList可以通过自己的add方法动态增加,而程序员不需要动态调节数组的容量。
C、ArrayList有get、set、add等方法,add方法可以添加一个数组,添加一个元素后,后续元素全部往后移动,这种添加效率较低,开销较大,因此长度较大且常执行添加、删除的数组,建议采用LinkList。
12、对象包装器与自动装箱
A、Java有八种基本类型,但是有时候需要将int这类基本类型转换为对象,这就需要有与之对应的类,int对象的类型是Integer,这种类被称为包装器(wrapper)。八种:Integer、Float、Double、Long、Short、Byte、Character、Void、Boolean。
B、对象包装器类是不可变的,即一旦构造了包装器,就不能再更改包装器中的值;同时这8个类是final类型的,不允许被继承。
C、假设定义一个整型数组,他的类型是不允许是基本类型,这里就需要用到Integer;同时添加元素的时候会发生“自动装箱”
ArrayList<Integer> alist=new ArrayList<>();
alist.add(3);//自动装箱,本剧代码会在执行时,自动变为下一句的写法
alist.add(Integer.valueOf(3));
13、参数可变的方法,java支持在方法中利用省略号(...)的方式来实现可变(不确定参数个数)参数;
//计算N个整数之和
public static int sum(int ...value){
int sum=0;
for(int i=0;i<value.length;i++){
sum=value[i]+sum;
}
return sum;
}
14、枚举类、定义:public enum Size{SMALL,MEDIUM,LARGER,EXTRA_LARGER}; 枚举类中可以定义方法和实例域。
15、反射(reflection )
A、Class类,获取三种方式:(1)e.getClass(); (2)Class.forName("java.util.int");(3)int.class;
B、能够分析类能力的程序称为反射(reflective);反射机制拥有极其强大的能力,他的使用者主要是是工具的构造者,而不是应用程序员;
16、利用反射分析类的能力,解析类
package com.supermap.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectionTest {
public static void main(String[] args) {
//1)利用反射的能力解析类
String name="java.lang.Integer";
try {
//类本身及集成
Class cl=Class.forName(name);
Class supercl=cl.getSuperclass();
String modifiers=Modifier.toString(cl.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
if(supercl!=null&&supercl!=Object.class)
System.out.println("extends:"+supercl.getName());
//开始分析构造函数
printConstructors(cl);
//开始分析方法
System.out.println("开始打印方法————————");
printMethods(cl);
//打印字段方法略
Field[] fields=cl.getFields();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 打印一个类的所有构造函数
*/
public static void printConstructors(Class cl){
Constructor[] constructors=cl.getDeclaredConstructors();
for(Constructor c:constructors){
String name=c.getName();
String modifiers=Modifier.toString(c.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
System.out.println(name+" (");
Class[] paramTypes=c.getParameterTypes();
for(int i=0;i<paramTypes.length;i++){
if(i>0)
System.out.println(", ");
System.out.println(paramTypes[i].getName());
}
System.out.println(");");
}
}
/**
* 打印一个类的所有方法
*/
public static void printMethods(Class cl){
Method[] methods=cl.getDeclaredMethods();
for(Method m:methods){
Class retType=m.getReturnType();
String name=m.getName();
String modifiers=Modifier.toString(m.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
System.out.println(retType.getName()+" "+name+"(");
Class[] paramTypes=m.getParameterTypes();
for(int i=0;i<paramTypes.length;i++){
if(i>0)
System.out.println(",");
System.out.println(paramTypes[i].getName());
}
System.out.println(");");
}
}
}
### 文末
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础

第二阶段:移动端开发技术

第三阶段:前端常用框架

* 推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;
* 大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
**开源分享:https://docs.qq.com/doc/DSmRnRGxvUkxTREhO**