JavaSE第二周复习需要注意的知识点

注:自用,无逻辑,复习到哪写到哪

逻辑运算符&&与&区别

&&的特点:如果左边为false则右边式子不再运行(短路效果)
&的特点:不管左边式子的结果如何,右边的式子都要运行

| 和 || 同理

		int i = 2;
		int j = 2;
		if((i++) != 2 & (j++) == 2){}
		System.out.println(i); // i=3
		System.out.println(j); // j=3
		int i = 2;
		int j = 2;
		if((i++) != 2 && (j++) == 2){}
		System.out.println(i); // i=3
		System.out.println(j); // j=2

<<、>>、>>>位运算符号

<< 左移 乘2的移动次数
/ >>右移 除2的移动次数
/>>>无符号右移 除2的移动次数(无符号)

		System.out.println(2 << 1); // 4
		System.out.println(2 >> 1); // 1

String、StringBuffer、StringBuilder区别

用Arrays.toString(int[] a)方法时,源代码里出现了StringBuilder
在这里插入图片描述

查询了一下String,StringBuffer,StringBuilder的区别

String:public final class String。
final定义,不可改变的字符串对象。

StringBuffer:public final class StringBuffer extends AbstractStringBuilder
代表一个字符序列可变的字符串对象,一旦通过StringBuffer生成了最终想要的字符串,可以调用toString()转换为一个String对象,实现了线程安全。

StringBuilder:public final class StringBuilder extends AbstractStringBuilder extends AbstractStringBuilder
也代表可变字符串对象,但StringBuilder没有实现线程安全功能,所以性能略高。

String和StringBuffer、StringBuilder转换
String -> StringBuffer/StringBuilder:
StringBuffer类中的构造方法:public String(String str);
StringBuilder类中的构造方法:public StringBuilder(String str);

StringBuffer -> String :
StringBuffer类:public String toString()

StringBuffer和StringBuilder异同
(1)StringBuffer和StringBuilder都继承于AbstractStringBuilder抽象类,
(2)StringBuffer和StringBuilder默认的字符数组元素个数都为16

public StringBuffer(){
	super(16);
}

public StringBuilder(){
	super(16);
}

(3)StringBuffer实现了线程安全,StringBuilder没有实现线程安全,因此性能较好

    //StringBuffer中的源代码
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    //StringBuilder中的源代码
	public StringBuilder append(double d) {
        super.append(d);
        return this;
    }

继承关系Super关键字的构造方法

super:代表的是父类的空间标识(代表父类对象的地址值引用)
继承关系中的初始化为分层初始化,需要将父类的数据初始化完毕后,再将子类的数据初始化。
(因为子类实例化对象时可能会用到父类中的成员变量)

class Father{
	private String name;
}

class Son{
	private int age;
	public Son(){
		//子类构造默认第一句为super()
		super();
	}
}

子类继承父类,子类中所有的构造方法都会默认先访问父类的无参构造方法(super())
如果父类没有无参构造,可以在子类的构造方法第一句添加super(参数)调用父类的其他构造方法.

super()有参数时,在子类相同参数构造函数调用时,改变的是父类的成员变量

class Father{
	private String name;
	public Father(String name){
		this.name = name;
	}
}

class Son{
	private int age;
	
//	//父类没有写无参构造,编译出错
//	public Son(){
//		//子类构造默认第一句为super()
//	}

	public Son(){
		super("father");
	}
}

局部代码块、静态代码块、构造代码块

局部代码块:定义在方法中,限定了代码块中变量的生命周期。

静态代码块:使用static修饰的代码块,随着类的加载而加载,同静态成员属性一样,只加载一次。

构造代码块:定义类中成员位置,用{}括起来的代码块,可以将多个构造方法中的共性代码抽取,放入构造代码块。

运行顺序:静态代码块 - 构造代码块 - 构造方法
如果一个类中存在new语句,则顺序为:静态代码块 - 从上到下new语句或构造代码块 - 构造方法最后执行。

class A{
	public A(){
	system.out.println("A");
	}
	{
		System.out.println("构造代码块1")}
	C c = new C(){
		System.out.println("构造代码块2")}
	static{
		System.out.println("静态代码块")}
}

class C{
	public C(){
		System.out.println("C");
	}
}

class B extends A{
	public static void main(){
		B b = new B();
	}
}

//执行结果:
//静态代码块
//构造代码块1
//C
//构造代码块2
//A

多态

java三大特征之一(封装、继承、多态)

多态:一个事物在不同时刻体现的不同形态

多态的前提条件:
1)必须要有继承关系
2)必须要有方法重写
3)必须有一个父类引用指向一个子类的对象(向上转型)

多态的成员访问特点:
(左为父类,右为子类)
1)成员变量:编译看左,运行看左
2)成员方法:编译看左,运行看右
3)构造方法:对当前对象中的数据进行初始化

class Father{
	public int num = 10;
	public void fun(){
		System.out.println("Father");
	}
}
class Son{	
	public int num = 20;
	public void fun(){
		System.out.println("Son");
	}
	public void fun2(){
		System.out.println("Son独有")}
}
class Test{	
	public void main(String args[]){
		Father fa = new Son();
		System.out.println(fa.num);
		fa.fun();
	}
}
//执行结果
//fa.num = 10;
//fa.fun(); = Son;

多态的弊端:
不能访问子类的独有的方法
解决办法:向下转型 ,即将父类引用再次转型为子类,前提是必须要先有向上转型。

class Test{
	public static void main(String args[]){
		Father fa = new Son();
		Son so = (Son)fa;
		so.fun2();
	}
}

//运行结果
//Son独有

内部类

内部类定义:内部类是指定义在类中的一个独立且完善的类结构
缺陷:破坏了程序的结构
优势:能够轻松的访问外部类的私有属性

//如果不使用内部类,通过内部类访问外部类的私有属性
class Outer{
	private String msg = "外部类私有属性";
	public String getMsg(){   //要想访问私有属性必须通过getter方法
		return this.msg;
	}
	public void fun(){
		Inner in = new Inner(this); //实例化内部类对象
		in.print()//调用方法
	}
}
class Inner{
	private Outer out = null;//要想调用Outer的get方法必须要有实例化对象
	public Inner(Outer out){ //通过构造函数获取一个Outer对象
		this.out = out;
	}
	public void print(){
		System.out.println("msg = " + this.out.getMsg()); //获取外部类的私有属性
	}
}
class Test{
	public static void main(String args[]){
		Outer out = new Outer();
		out.fun();
	}
}

如果定义成内部类,则内外部类访问对方的私有属性不再通过getter方法

class Outer{
	private String msg = "外部类私有属性";
	public void fun() {
		Inner in = new Inner();
		in.print();
		System.out.println(in.info);
	}
 
//可以用Private修饰
	class Inner{
		private String info = "内部类的私有属性";
		public void print() {
		System.out.println(msg);
	}
}
public class InnerClass {
	public static void main(String[] args) {
	Outer out = new Outer();
	out.fun();
	}
}

具有内部类的类,在编译后会自动形成一个Outer(美元符号)Inner.class的类文件,其中$符号在java里等同于.
因此当内部类没有被private修饰,可以直接在外部实例化内部类的对象。

public class InnerClass {
 	public static void main(String[] args) {
 		Outer.Inner in = new Outer().new Inner();、
 		in.print();
	}
}

static修饰内部类 ,则内部类相当于外部类,内部类的属性和方法不能用static修饰

class Outer{
private static final String MSG = "外部类私有属性";
	static class Inner{
		public void print() {
 		System.out.println(Outer.MSG);
  		} 
  	}
}
public class StaticInner {
	//要想实例化inner类对象,只需要根据外部类.内部类的结构实例化对象即可
	public static void main(String[] args) {
	//外部类.内部类 内部类对象 = new 外部类.内部类()
	//对比: Outer.Inner in = new Outer().new Inner();
	        Outer.Inner in = new Outer.Inner();
		in.print();
	}
}

总结:内部类最大的优势是可以访问外部类的私有属性,一般运用在一些内部结构不需要被外部操作,只需要被外部类操作的情况,例如链表。

Lambda表达式

jdk8引入了Lambda表达式,本质是实现了函数式编程,使得代码更加简洁。要想实现Lambda表达式,必须满足SAM(Single Abstract Method),即只有一个抽象方法。

只有一个抽象方法的接口称为函数式接口,能被Lambda所使用的。
注解:@FunctionalInterface

  • Lambda表达式:
  • 1 方法没有参数:()->{};
  • 2 方法有参数:(参数,参数)->{};
  • 3 如果现在只有一行语句返回:(参数,参数)->语句;

@FunctionalInterface
interface IMessage{ 
	public void send(); //方法没有参数
}

@FunctionalInterface
interface IMessage2{ 
 	public void send(String msg); //方法有参数
}

@FunctionalInterface
interface IMath{	
	public int sum(int a,int b);//方法有返回值
}

class JavaDemo{
	public static void main(String args[]){
		IMessage msg = ()->{
			System.out.println("无参数方法");
		};
		msg.send(); //结果:无参数方法
		
		IMessage2 msg2 = (str)->{
			System.out.println(str);
		};
		msg2.send("有参数方法"); //结果:有参数方法
		
		IMath math = (a,b)->{
			return a + b;
		};
		System.out.println(math.sum(10,5));//结果:15
	}   
}

函数式接口同样可以添加static和default方法,都是jkd8的新特性,为函数式接口服务

@FunctionalInterface
interface IMessage{	
	public void send(String str);		
	public default void print() {} 
}

Runnalbe接口也是函数式接口,因此可以使用Lambda表达式

  Runnable run = ()->{
  	System.out.println("runnable");
  } ;
  
  Thread myThread = new Thread(run);
  myThread.start();

系统提供的函数式接口在java.util.function的开发包,里面有可以直接使用的函数式接口
(1)功能性函数式接口
@FunctionalInterface
public interface Function<T,R>{
public R apply(T t);
}

(2)消费型函数式接口。只能够进行数据的处理操作,而没有任何返回
@FunctionalInterface
public interface Consumer{
public void accept(T t);
}

(3)供给型函数式接口
@FunctionalInterface
public interface Supplier{
public T get();
}

(4)断言型函数式接口。进行判断处理
@FunctionalInterface{
public interface Predicate{
public boolean test(T t);
}

public class FunctionDemo {
	public static void main(String[] args) {
		Function<String,Boolean> fun = "**Hello" :: startsWith;
		System.out.println(fun.apply("**")); //true
  		
  		Consumer<String> fun1 = System.out :: println;	
		fun1.accept("接收"); //接收
  
		Supplier<String> fun2 = "ABCD" :: toLowerCase;
		System.out.println(fun2.get()); //abcd
  
		Predicate<String> fun3 = "abcd" :: equalsIgnoreCase;
		System.out.println(fun3.test("abcd"));  //true
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值