java基础
java基础知识点
java基础知识点记录
1,作用域public,private,protected,以及不写时的区别
实际上,把重要的数据修饰为private,然后写一个public的函数访问它,正好体现了OOP的封装特性,是OOP安全性的体现
访问权限修饰符修饰类时需要注意:
1、不能用protected和和private修饰类
2、用friendly修饰的类叫友好类,在另外一个类中使用友好类创建对象时,要保证它们在同一包中
2,关于String s2=new String( “Hello “)创建几个对象的分析
视情况而定,当常量池中没有“Hello”对象时是创建两个,一个存放在常量池中,另一个存放在堆(内存)中(new String 产生)
并把这个堆内存中的String对象的引用返回给s2,String s2是栈中创建了的一个变量
如果是String s = “xyz”,那就要看常量池里有没有”xyz”,如果有直接引用,如果没有则创建再引用
3,==与equals
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一对象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}
4,抽象类和接口
抽象类
1、抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。 2、抽象方法必须由子类来进行重写。 3、只要包含一个抽象方法的抽象类,该方法必须要定义成抽象类,不管是否还包含有其他方法。 4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。 5、子类中的抽象方法不能与父类的抽象方法同名。 6、abstract不能与final并列修饰同一个类。 7、abstract 不能与private、static、final或native并列修饰同一个方法。、 `接口` 1、个Interface的方所有法访问权限自动被声明为public。确切的说只能为public,当然你可以显示的声明为protected、private,但是编译会出错! 2、接口中可以定义“成员变量”,或者说是不可变的常量,因为接口中的“成员变量”会自动变为为public static final。可以通过类命名直接访问:ImplementClass.name。 3、接口中不存在实现的方法。 4、实现接口的非抽象类必须要实现该接口的所有方法。抽象类可以不用实现。 5、不能使用new操作符实例化一个接口,但可以声明一个接口变量,该变量必须引用(refer to)一个实现该接口的类的对象。可以使用 instanceof 检查一个对象是否实现了某个特定的接口。例如:if(anObject instanceof Comparable){}。 6、在实现多接口的时候一定要避免方法名的重复。
5,重载和重写
a,重载
概念:对于同一个类,如果这个类里面有两个或者多个重名的方法,但是方法的参数个数、类型、顺序至少有一个不一样,这时候局构成方法重载
作用:方法重载就是对不同数据类型的的数据实现相似的操作
说明:在Test类中有两个方法,名字都相同,都是a。在调用方法a时,如果不传参数,则系统会自动调用第一个方法a;如果传入一个 int 类型的参数,则系统调用第二个方法a
//example1
public class Test{
public void a( ){
};
public void a( int i){
};
}
//example2
public class Test{
public void a(int i,String j){
}
public class a(String j,int i){
}
}
b,重写
概念:当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。
重写也是覆盖 override
前提:需要有继承关系
特点:当子类重写了父类的函数,那么子类的对象如果调用该函数,一定调用的是重写过后的函数;可以通过super关键字进行父类的重写函数的调用;继承可以使得子类增强父类的方法
细节:
1函数名必须相同
2参数列表必须相同
3子类重写父类的函数的时候,函数的访问权限必须大于等于父类的函数的访问权限否则编译报错
4子类重写父类的函数的时候,返回值类型必须是父类函数的返回值类型或该返回值类型的子类,不能返回比父类更大的数据类型
//examples
class Animal{
int x=1;
String name;
void eat(){
System.out.println("吃东西");
}
void shout(){
System.out.println("我是动物");
}
}
class Dog extends Animal{
void eat(){
System.out.println("啃骨头");
}
void shout(){
System.out.println("旺旺");
}
void eat(String food){
System.out.println("吃:"+food);
}
}
class Cat extends Animal{
void eat(){
System.out.println("吃老鼠");
}
void shout(){
System.out.println("喵喵");
}
}
class Demo9{
public static void main(String[] args){
Dog d=new Dog();
d.shout();
d.eat();
Cat c=new Cat();
c.shout();
c.eat();
System.out.println();
}
//原文:https://blog.csdn.net/qq_32575047/article/details/79949823
c,重载和重写的不同
1:重载(overload):
前提: 所有的重载函数必须在同一个类中
特点: 函数名相同,参数列表不同,与其他的无关(访问控制符、返回值类型)
不同:个数不同 、 顺序不同、 类型不同
重写(override):
前提: 继承
特点:函数名必须相同、参数列表必须相同;子类的返回值类型要等于或者小于父类的返回值类型
d,构造器能否被重写
构造器是不能被继承的,因为每个类的类名都不相同,而构造器名称与类名相同,所以根本谈不上继承 又由于构造器不能继承,所以就不能被重写。但是,在同一个类中,构造器是可以被重载的
6,List
- 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型。
- append() 方法向列表的尾部添加一个新的元素。
- 列表是以类的形式实现的。“创建”列表实际上是将一个类实例化。因此,列表有多种方法可以操作。
extend()
方法只接受一个列表作为参数,并将该参数的每个元素都添加到原有的列表中。
7,forward和redirect的区别
转发是服务器行为,重定向是客户端行为
forward(转发):
是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程是在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址.
redirect(重定向):
是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
8,多线程
Runnable对象作为Thread对象的target,Runnable实现类里面包含run方法仅仅作为执行体。也就是说Thread类的作用是把run方法包装成线程的执行体。
实际运行的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run方法
调用的是哪个run方法
//代码1
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Run of Runnable");
}
}) {
public void run() {
System.out.println("Run of Thread");
}
}.start();
//代码2
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Run of Runnable");
}
}) {
public void run() {
System.out.println("Run of Thread");
super.run();
}
}.start();
JDK的Thread源码,片段 3
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
在run()方法中,首先会检查target是否为空,如果不是,则执行该target的run()方法。
那么,对于上面两段代码的执行,也就清楚了。
在第一个代码段 1 中,重写了Thread的run()方法,同时传入了一个Runnable对象,该对象也实现了run()方法。该Thread对象调用start()方法后,会执行该对象重写的run()方法,其输出结果也就是Run of Thread,输出完后,run()方法返回,该线程对象的生命周期也就结束了。
在第二个代码段 2 中,同样也重写了Thread的run()方法,同时传入了一个Runnable对象,实现了run()方法。唯一不同的是,在Thread重写的run方法中,在打印输出后,还执行了super.run(),这就有意思了。
首先,该线程启动运行后,执行其重写的run()方法,输出Run of Thread。
接下来调用super.run(),也就是调用超类的run()方法,而该超类的run()方法,也就是JDK定义的Thread类的run(),其执行如上代码段 3 所示;显然target不为空,这时候会调用该对象的run()方法,会输出Run of Runnable.。
如果,上面的Thread并未重写run()方法,那么,执行的结果还是一样。首先会执行该Thread的run()方法,因为此时并未重写该方法,所以还是会调用JDK定以的run()方法,也就是上面的代码段 3,在该代码段中会判断target是否为空,显然不是,所以会调用Runnable对象实现的run()方法。
总结:对于Thread(Runnable target …),不管传入的Target是否为空,首先都会执行Thread自己的run()方法。如果重写了该方法且该方法中没有super.run(),那么是永远不会调用Runnable实现的run()方法;如果没有重写该方法,则会去判断target是否为空,以此来决定调用target实现的run()方法;如果重写了该方法,且该方法中有super.run(),在执行完该语句之前的所有代码后,会判断target是否为空,以此来决定调用target实现的run()方法,执行完后,接着执行该语句之后的代码。
9,HashMap的基本用法
- 创建HashMap对象
HashMap<String,Integer> hashMap = new HashMap<>();
- 添加键值对
hashMap.put("aa",1);
hashMap.put("bb",2);
hashMap.put("cc",3);
//添加元素时,如果key已经存在,则返回旧value,并将新的value存到该key中;如果key不存在,则返回null
put方法会覆盖原有的value,而另一种put方法不会覆盖:putIfAbsent(key,value)
hashMap.putIfAbsent("aa",4);
该方法首先会判断key是否存在,如果存在且value不为null,则不会覆盖原有的value,并返回原来的value;如果key不存在或者key的value为null,则会put进新值,并返回null。
另外,两种方法当key=null时,并不会抛出异常,而是按照一个特殊的方法进行存储
- 删除元素
remove(key):删除成功(存在key),返回被删除的key对应的value,否则返回null。
remove(key,value):删除成功(存在entry),返回true,否则返回false。
hashMap.remove("bb");
hashMap.remove("aa",5);
- 获取元素
对于获取元素,有get(key)和getOrDefault(key,defaultValue)(1.8之后)两种方法.
hashMap.get("cc")
getOrDefault在key不存在时,返回一个defaultValue。在没有该方法前需要这样写:
Integer bbValue = hashMap.containsKey("bb")?hashMap.get("bb"):-1;
有了getOrDefault可以这样写:
getOrDefault("aa",-1)//key=aa不存在,所以返回默认value -1
- 元素遍历
Iterator iterator1 = hashMap.entrySet().iterator();
while (iterator1.hasNext()){
Map.Entry entry = (Map.Entry) iterator1.next();
String key = (String) entry.getKey();
Integer value = (Integer) entry.getValue();
System.out.println(key+"="+value);
}
- 判断key或value是否存在
hashMap.containsKey("aa");
hashMap.containsValue(1);
- 替换元素
replace方法用来替换元素。
hashMap.replace("ff",5);
对于存在的key,调用replace方法,会替换原来的value,并返回旧value,这和put的效果是一样的;对于不存在的key,replace方法什么都不做。这就是他和put的区别(put在key不存在时将新key-value加入map)
10,Map的使用
HashMap,TreeMap,LinkedHashMap的简单应用
HashMap是随机的,TreeMap是按照元素的大小顺序排列的,LinkedHashMap是按照添加的顺序排列的。
package com.lxk.collectionTest;
import com.google.common.collect.Maps;
import java.util.Map;
/**
* 测试Map是否有序的区别
* <p>
* Created by lxk on 2017/5/24
*/
public class OrderedMapTest {
public static void main(String[] args) {
Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
System.out.println("--------------test hashMap");
testMap(hashMap);
System.out.println("--------------test treeMap");
testMap(treeMap);
System.out.println("--------------test linkedHashMap");
testMap(linkedHashMap);
}
private static void testMap(Map<String, Integer> map) {
map.put("asd", 1);
map.put("2das", 2);
map.put("3das", 3);
map.put("4das", 4);
//这也是map的一种遍历方式,增强for
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
结果如下:
- 100周年党庆习总书记讲话(全文)
- 《这个社会会好吗》 熊培云/著
- 备忘单词本
- 新闻随笔记录
- 党的基本
- 申论/素材
- 申论/笔记2-李梦圆
- 申论/笔记1-中公
- 申论/笔记0
- 行测/资料分析20题
- 行测/言语理解40题
- 行测/常识判断20题
- 行测/判断推理40题
- 美其名
- 博学从书
- 《沧浪之水》 阎真/著
- 面试/经验总结
- 《习近平的七年知青岁月》 中共中央党校出版社/著
- PHP
- Linux命令
- Linux2举例跟踪分析Linux内核5.0系统调用处理过程
- Linux1基于mykernel的简单时间片轮转多道程序内核代码分析
- Linux3分析进程创建、执行、切换以及可执行文件的加载
- dataBase学习记录
- Eclipse
- JVM简单理解
- Jekyll应用经验
- git命令记录
- java基础