1.重写与重载的区别
重载规则:
方法名相同,参数个数或类型不同,与返回值类型无关,节约词汇,例如driver.switchTo().frame(index/nameOrId/frameElement)
java的重载(overload) 最重要的应用场景就是构造器的重载,目的是对方法(构造器)进行功能扩展,以应对多业务场景的不同使用需求。提高程序的健壮性和扩展性
重写规则:
建立在继承关系上,子类和父类的方法名称,参数类型,返回值类型全部相同,不仅可以得到父类的东西,同时也加入了自己的东西,重用性,扩展性,复用性,
简单总结:
重载是多样性,重写是增强剂;
目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展;
目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写;
生活例子:
你想吃一碗面,我给你提供了拉面,炒面,刀削面,担担面供你选择,这是重载;
你想吃一碗面,我不但给你端来了面,还给你加了青菜,加了鸡蛋,这个是重写;
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
2.==“和equals方法究竟有什么区别
"和equals方法究竟有什么区别?
==:用于基本类型数据的比较,比较的是值
用于引用数据类型的比较所指向的对象的地址
equals:不能用于基本类型的数据的比较
用于引用类型的比较:
如果没有对equals进行重写,比较的是引用类型的变量所指向的对象的地址
如果对equals进行重写,比较的是所指向的对象的内容(String/Date)又可分为两种情况:
hashcode进行重写:
如果相同,equals()方法返回值不能确定,可能为true,也可能为false
不相同,用equals()方法判断返回的一定是false
不对hashcode进行重写,用equals()方法判断返回的一定是true
3.static的基本用法
static:表示“全局”或“静态”的意思,修饰类的成员方法和成员变量,也可以编写static代码块优化程序性能
a.static修饰的成员方法
一般称为“静态方法”,它不依赖于任何对象就能进行访问,可以使用“ 类名.方法名”的方式操作方法,避免了先要new出对象的
繁琐和资源消耗,它也没有this和super关键字,静态方法中不能访问非静态成员变量和非静态成员方法,因为非静态成员变量和
非静态成员方法必须依赖具体的对象才能够被调用,但是对于非静态成员方法是可以访问静态成员方法和静态变量的。
b.static修饰的变量
一般称为“静态变量”或“类变量”,静态变量与非静态变量的区别是:静态变量所在的类的所有对象共享这一个属性(不同的类中不共享),
在内存中只有一个副本,它当且仅当在类初始加载时才会被初始化,非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本,
各个对象拥有的副本相互不影响,可以用“类名.静态变量”或“对象.静态变量”进行访问,但“类名.静态变量”更能体现出static的作用。
局部变量不能声明为静态变量。static变量进行初始化时有默认值,final static初始化时必须有初始值
以下两种情况使用static变量:(1)静态变量所在的类的所有对象直接共享数据(2)访问变量时
c.static代码块
一般称为“静态代码块”,可放在类中的任何地方,类中可有多个static代码块,在类初次被加载时会按照static代码块顺序来执行每个static
代码块并且只会执行一次,静态代码块不能放在任何方法的内部
**总结:**static的基本作用:方便在没有创建对象情况下调用方法/变量
4.接口和抽象类的区别
接口是对行为的抽象,接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现
特点:
接口中可以含有变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。
从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。
如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。对于遵循某个接口的抽象类,可以不实现该接口中的抽象方法。
抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中没有任何意义,必须根据子类的实际需求来进行
特点:
abstract修饰的类为抽象类,此类不能有对象,(无法对此类进行实例化); abstract修饰的方法为抽象方法,是抽象方法,此方法不能有方法体(为空),包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
在接口和抽象类的选择上,必须遵守这样一个原则:
行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能
5.深拷贝和浅拷贝的区别是什么?
浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象
深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍.
6.文件读取
FileInputstream / FileOutputstream
FileReader / FileWriter
7.List,Set,Map三者的区别
List(对付顺序的好帮手): List接口存储一组不唯一(可以有多个元素引用相同的对象),有序
的对象
Set(注重独一无二的性质): 不允许重复的集合。不会有多个元素引用相同的对象。
Map(用Key来搜索的专家): 使用键值对存储。Map会维护与Key有关联的值。两个Key可以引用相同的对象,但Key不能重复,典型的Key是String类型,但也可以是任何对象
8.创建对象有几种方式
new、反射、clone 拷贝、反序列化。
9.String、String StringBuffer 和 StringBuilder 的区别是什么
String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。
StringBuffer和StringBuilder他们两都继承了AbstractStringBuilder抽象类,从AbstractStringBuilder抽象类中我们可以看到, 他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用StringBuffer和StringBuilder来进行操作。 另外StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
10.反射的基础应用
概述:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个属性和方法,这种能够动态获取信息以及动态调用对象的方法的功能称为Java的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象,而解剖使用的就是Class类中的方法,所以先要获得
每一个字节码文件对应的Class类型的对象。反射就是把Java类中的各种成分映射成一个个的Java对象
一.Class类:代表一个类
Field类:代表类的成员变量(类的属性)
Method类:代表类的方法
Construtor类:代表类的构造方法
Arrary类:提供了动态创建数组以及访问数组的元素的静态方法
要想操作反射,必须先拿到反射的入口
获取Class对象的三种方式
* 1 Object ——> getClass();//对象都有了还要反射干什么
* 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性//需要导入类的包,依赖太强,不导包就抛编译错误
* 3 通过Class类的静态方法:forName(String className)(常用)//,一个字符串可以传入也可写在配置文件中等多种方法
二.通过Class对象获取类中的获取单个的"公有的"构造方法
1、public Constructor getConstructor(Class… parameterTypes):获取单个的"公有的"构造方法
parameterTypes:构造方法中的形参类型,例如String.class
2.调用构造方法
Constructor–>newInstance(Object… initargs)
initargs:形参的具体值
三.通过Class对象获取类中的“公有”的方法
1.public Method getMethod(String name,Class<?>… parameterTypes):
name : 方法名;
Class … : 形参的Class类型对象
举例:
//获取公有的构造方法
Constructor con = clazz.getConstructor(String.class);
con.newInstance(“曹心情构造方法”);
2.调用方法
Method --> public Object invoke(Object obj,Object… args)
obj : 要调用方法的对象;
args:调用方式时所传递的实参;
注意:要调用方法的对象obj需要用到构造方法,实例化一个对象
Object obj = clazz.getConstructor().newInstance();
另外如果方法是静态的,obj可以省略,直接写null
举例:
//获取公有的setName()方法
Method m = clazz.getMethod(“setName”, String.class);
Object obj = clazz.getConstructor().newInstance();
m2.invoke(obj, “曹普通方法”);
11.fastjson基本使用
一.Json格式
1.1 JSON对象:
{
“name”: “张三”,
“age”: 24
}
1:数据在花括号中
2:数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象)
3:每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号)
1.2:JSON对象数组
[
{“name”: “张三”, “age”: 24},
{ “name”: “王五”, “age”: 22}
]
1:数据在方括号中(可理解为数组)
2:方括号中每个数据以json对象形式出现
3:每两个数据以逗号分隔(最后一个无需逗号)
1.3:两种形式的结合
{
“部门名称”:“研发部”,
“部门成员”:[
{“name”: “张三”, “age”: 24},
{“name”: “王五”, “age”: 22}],
“部门位置”:“xx楼21号”
}
1.4:JSON字符串
1:它必须是一个字符串,由" "或者’ '包裹数据,支持字符串的各种操作
2:里面的数据格式应该要满足其中一个格式,可以是json对象,也可以是json对象数组或者是两种基本形式的组合变形
总结:json可以简单的分为基本形式:json对象,json对象数组。两种基本格式组合变形出其他的形式,但其本质还是json对象或者json对象数组中的一种。json对象或对象数组可以转化为json字符串,使用于不同的场合。
注意点:在封装json数据的时候,很容易出现错误,比如粗心的在最后一条数据的末尾加上了逗号等等,这里我提供一个在线验证工具,方便大家验证json数据格式的正确性
http://www.bejson.com/
二:fastJson的使用
JSONObject和JSONArray继承JSON,JSON代表JSONObject和JSONArray的转化,JSON类主要是实现转化用的,最后的数据获取,还是要通过上面的JSONObject和JSONArray来实现
JSONObject代表json对象,底层操作是由Map实现的,通过"键:值"对中的键来获取其对应的值,通过各种形式的get()方法可以获取json对象中的数据
JSONArray代表json对象数组,底层操作由List实现的,因为JSONArray代表json对象数组,json数组对象中存储的是一个个json对象,所以类中的方法主要用于直接操作json对象
1.JSON类之toJSONString()方法,实现json对象转化为json字符串和javabean对象转化为json 字符串
2.JSON类之parseObject()方法,实现json字符串转换为json对象或javabean对象:
Student stu1=JSON.parseObject(jsonstr,Student.class);
3.parseArray()将json字符串转化为json对象数组或转化成包含泛型的List
三.举例使用
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public class StudentGroup {
private String username;
private List stus = new ArrayList();
public StudentGroup(){}
public StudentGroup(String username, List stus) {
this.username = username;
this.stus = stus;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List getStus() {
return stus;
}
public void setStus(List stus) {
this.stus = stus;
}
@Override
public String toString() {
return “StudentGroup [username=” + username + “, stus=” + stus + “]”;
}
}
public class FastJson {
public static void main(String[] args) {
List stus = new ArrayList();
Student student1=new Student(“bob”,24);
Student student2=new Student(“lily”, 23);
stus.add(student1);
stus.add(student2);
System.out.println(“简单java类转json字符串”);
String str1=JSON.toJSONString(student1);
System.out.println(str1);
System.out.println();
System.out.println(“List转json字符串”);
System.out.println(JSON.toJSONString(stus));
System.out.println();
System.out.println(“复杂java类转json字符串”);
StudentGroup group = new StudentGroup(“StudentGroup”, stus);
String GroupJson = JSON.toJSONString(group);
System.out.println(GroupJson);
System.out.println();
/**
* json字符串转java对象
* 注:字符串中使用双引号需要转义 (" --> “),这里使用的是单引号
/
/ json字符串转简单java对象
* 字符串:{“password”:“123456”,“username”:“dmego”}/
System.out.println(“json字符串转简单java对象”);
String jsonStr1 = “{‘name’:‘曹新晴’,‘age’:‘30’}”;
Student student = JSON.parseObject(jsonStr1, Student.class);
System.out.println(student.toString());
System.out.println();
/
* json字符串转List对象
* 字符串:对象数组[{“age”:24,“name”:“bob”},{“age”:23,“name”:“lily”}]
* 如果字符串是 对象,比如 {‘name’:‘曹新晴’,‘age’:‘30’}”,就需要先转换成Map,再转换成List
*/
System.out.println(“json字符串转List对象”);
String jsonStr2 = “[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]”;
List students = JSON.parseArray(jsonStr2, Student.class);
System.out.println(students.toString());
System.out.println();
System.out.println(“json字符串转复杂java对象”);
String jsonStr3 = “{‘username’:‘StudentGroup’,‘stus’:[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]}”;
StudentGroup studentGroup = JSON.parseObject(jsonStr3, StudentGroup.class);
System.out.println(studentGroup);
String jsonStr4 = “[{‘username’:‘StudentGroup’,‘stus’:[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]},{‘username’:‘StudentGroup2’,‘stus’:[{‘age’:34,‘name’:‘bob2’},{‘age’:33,‘name’:‘lily2’}]}]”;
List parseArray = JSON.parseArray(jsonStr4, StudentGroup.class);
System.out.println(“parseArray:”+parseArray);
System.out.println();
System.out.println(“json字符串转Map对象”);
String jsonStr5 =“{‘mobilephone’:‘13517315120’,‘pwd’:‘315120’}”;
Map<String, String> map = JSON.parseObject(jsonStr5, Map.class);
}
}
12.内存分配
堆内存
用来存放由new创建的对象实例和数组。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。访问对象需靠引用变量(栈中创建),常量池存在于堆中。
栈内存
栈用于存储程序运行时在方法中声明的所有局部变量(栈主要存储方法中的局部变量)包括:1.用来保存基本数据类型的值。特点:栈内存的数据用完就释放
方法区(静态区)
用于存放类的各种信息(包括方法)都在方法区存储。(将类的成员都加载到方法区)和static变量