Java小记

357 阅读9分钟

接口的高级应用

/*接口类*/
public interface MsgListener{
	public void afterMsgRecived(String msgData);
}
/*工具类*/
public class Tools{
	public static void getMsgData(String reciver,MsgListener listener){
		reciver+=reciver;
		//关键的来了
		listener.afterMsgRecived(reciver);
	}
}

/*调用类*/
public static void main(String[] args){
	String reciver="JACK THE REAPER";
	//调用
	Tools.getMsgData(reciver,new MsgListener(){
		@override
		public void afterMsgRecived(String msgData){
			System.out.println(msgData);
		}
	});
}

你会看到控制台输出:"JACK THE REAPERJACK THE REAPER";

ArrayList 和 LinkedList 有什么区别?

  • ArrayList 数据结构是==数组== ==查找效率更高==

  • LinkedList 数据结构是==双向链表== ==增加删除效率高==

  • LinkedList 更占用内存

final 的用途

  • final 修饰的类叫最终类,该类不能被继承。
  • final 修饰的方法不能被重写。
  • final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。

equals与hashcode的关系

equals相等两个对象,则hashcode一定要相等。但是hashcode相等的两个对象不一定equals相等。

public、 private 、protect、

  • public: Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包(package)访问。
  • private: Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的类、属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问
  • protect: 介于public 和 private 之间的一种访问修饰符,一般称之为“保护形”。被其修饰的类、属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。

单例模式

饿汉式 好处是没有线程安全的问题,坏处是浪费内存空间。

public class Singletion {
    private static Singletion instance = new Singletion();//饿汉式 在初始化时就先创建好对象 ,获取对象的时候直接返回
    public Singletion(){

    }
    public static Singletion getInstance(){
        return instance;
    }
}

懒汉式 有线程安全和线程不安全两种写法,区别就是synchronized关键字。

线程不安全

public class Singletion {
    private static  Singletion instance;
    public Singletion (){

    }
    public static  Singletion getInstance(){
        if(instance == null){
            instance = new Singletion();//用的时候才去检查有没有实例,如果有则返回,没有则新建。
        }
        return instance;
    }
}

线程安全

public class Singletion {
    private static  Singletion instance;
    public Singletion (){

    }
    public static  synchronized Singletion getInstance(){
        if(instance == null){
            instance = new Singletion();//用的时候才去检查有没有实例,如果有则返回,没有则新建。
        }
        return instance;
    }
}

双重检查

public class Singletion {
    private volatile static  Singletion instance;
    public Singletion (){
    }

    public static  Singletion getInstance(){
        if(instance == null){
            synchronized(Singletion.class){
                if (instance == null){
                    instance = new Singletion();
                }
            }
        }
        return instance;
    }
 }   

静态类

public class Singletion {  
    private static class SingletionHolder {  
    private static final Singletion INSTANCE = new Singleton();  
    }  
    private Singletion (){}  
    public static final Singletion getInstance() {  
    return SingletionHolder.INSTANCE;  
    }  
}

工厂模式

  • 意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
  • 主要解决:主要解决接口选择的问题。
  • 应用实例: 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
  • 实现
    在这里插入图片描述

步骤1:创建一个接口

public interface Shape {
   void draw();
}

步骤 2:创建实现接口的实体类。

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("画一个矩形");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("画一个圆");
   }
}

步骤 3 创建一个工厂,生成基于给定信息的实体类的对象。

public class ShapeFactory {
    
   //使用 getShape 方法获取形状类型的对象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Rectangle();
      }
      return null;
   }
}

步骤 4 使用该工厂,通过传递类型信息来获取实体类的对象。

public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //获取 RECTANGLE 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("RECTANGLE");
 
      //调用 RECTANGLE 的 draw 方法
      shape1.draw();
 
      //获取 CIRCLE 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("CIRCLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();

   }
}

输出结果

画一个矩形
画一个圆

观察者模式

  • 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
  • 主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

实现 观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。

在这里插入图片描述
步骤 1 创建 Subject 类

import java.util.ArrayList;
import java.util.List;
 
public class Subject {
   
   private List<Observer> observers 
      = new ArrayList<Observer>();
   private int state;
 
   public int getState() {
      return state;
   }
 
   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }
 
   public void attach(Observer observer){
      observers.add(observer);      
   }
 
   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }  
}

步骤 2 创建 Observer 类。

 public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

步骤 3 创建实体观察者类。

public class BinaryObserver extends Observer{
 
   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "int类型的变量转换为二进制表示的字符串-->" 
      + Integer.toBinaryString( subject.getState() ) ); 
   }
}
public class HexaObserver extends Observer{
 
   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
 
   @Override
   public void update() {
      System.out.println( "int类型的变量转换为十六进制表示的字符串-->" + Integer.toHexString( subject.getState() ).toUpperCase() ); 
   }
}

步骤 4 使用 Subject 和实体观察者对象。

public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();
      
      new BinaryObserver(subject);
      new HexaObserver(subject);
 
      System.out.println("第一次改变-->15");   
      subject.setState(15);
      System.out.println("第二次改变--> 10");  
      subject.setState(10);
   }
}

输出

第一次改变-->15
int类型的变量转换为二进制表示的字符串-->1111
int类型的变量转换为十六进制表示的字符串-->F
第二次改变-->10
int类型的变量转换为二进制表示的字符串-->1010
int类型的变量转换为十六进制表示的字符串-->A

equals和hashCode的区别

如果两个对象equals, 他们的hashcode一定相等。 如果两个对象不equals,他们的hashcode有可能相等。 如果两个对象hashcode相等,他们不一定equals。 如果两个对象hashcode不相等,他们一定不equals。

== 和 equals 的区别是什么?

  • 比较基本类型只能用==,比较结果你看到的字面值相等就会相等,基本类型不存在用equals比较.
  • 较引用类型(对象),==比较的是两个引用是不是指向同一个内存地址,equals比较的是两个引用的字面值是不是相同

Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?

答:Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。

指出下面程序的运行结果。

class A {
 
    static {
        System.out.print("1");
    }
 
    public A() {
        System.out.print("2");
    }
}
 
class B extends A{
 
    static {
        System.out.print("a");
    }
 
    public B() {
        System.out.print("b");
    }
}
 
public class Hello {
 
    public static void main(String[] args) {
        A ab = new B();
        ab = new B();
    }
 
}

答:执行结果:1a2b2b。创建对象时构造器的调用顺序是:先初始化静态成员,然后调用父类构造器,再初始化非静态成员,最后调用自身构造器。

什么是隐式转换,什么是显式转换

显示转换就是类型强转,把一个大类型的数据强制赋值给小类型的数据;隐式转换就是大范围的变量能够接受小范围的数据;隐式转换和显式转换其实就是自动类型转换和强制类型转换。

接口有什么特点?

接口中声明全是public static final修饰的常量 接口中所有方法都是抽象方法 接口是没有构造方法的 接口也不能直接实例化 接口可以多继承

接口与抽象类有什么区别?

抽象类有构造方法,接口没有构造方法 抽象类只能单继承,接口可以多继承 包含抽象方法的类,一定是抽象类。 抽象类可以有普通方法,接口中的所有方法都是抽象方法 接口的属性都是public static final修饰的,而抽象的不是

抽象类能使用 final 修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,

Collection接口下有那些集合框架?

List:线性表、Set:无序集合。

List接口有什么特点?

顺序存储、可以有重复值。

Set接口有什么特点

无序存储、不能有重复值。

Map有什么特点

以键值对存储数据 元素存储循序是无须的 不允许出现重复键

Java集合框架

在这里插入图片描述
在这里插入图片描述

java的异常

Java 的异常处理模型基于三种操作 :

  • 声明一个异常 ( declaring an exception )
  • 抛出一个异常 ( throwing an exception )
  • 捕获一个异常 ( catching an exception )

finally关键字

  • 在任何情况下 , finally 块中的代码都会执行
  • 如果 try 块中没有出现异常 , 也会执行finally块里的语句。
  • 如果 try 块中有一条语句引起异常 ,并且被catch块捕获 ,就会跳过 try 块剩余的语句 , 执行 catch 块和 finally 子句 。接着执行try 语句之后的下一条语句 。
  • 如果 try 块中有一条语句引起异常 , 但是没有被任何 catch 块捕获 , 就会跳过 try 块中的其他语句 , 执行 finally 子句 , 并且将异常传递给这个方法的调用者 。即使在到达 finally 块之前有一个return 语句 , finally 块还是会执行 。
  • 使用 finally 子句时可以省略掉 catch 块 。

throw、throws关键字 throw关键字:语句抛出异常

语法:throw (异常对象);

throws关键字:声明异常(方法抛出一个异常)

语法: (修饰符)(返回值类型)(方法名)([参数列表])[throws(异常类)]{......} public void doA(int a) throws Exception1,Exception3{......}

  • throw 后面跟的是对象,throws后面跟的是异常类
  • throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。
  • throws语句用在方法声明后面,表示再抛出异常,由调用这个方法的上一级方法中的语句来处理,必须做出处理(捕获或继续声明)
  • throws主要是声明这个方法会抛出这种类型的异常,使其他地方调用它时知道要捕获这个异常,使得提醒必须做出处理。否则编译是不会通过的。

需要包含 XXXXX 的封闭实例

UserStruct.ByReference idBuffer =new UserStruct().ByReference();
ByReference 不是静态类,因此不能使用“外部类.内部类”的形式。
解决方案1:将ByReference更改为静态类
解决方案2:UserStruct.ByReference idBuffer =new UserStruct().new ByReference();