Java小记

文章目录

        • 接口的高级应用
        • ArrayList 和 LinkedList 有什么区别?
        • final 的用途
        • equals与hashcode的关系
        • public、 private 、protect、
        • 单例模式
        • 工厂模式
        • 观察者模式
        • equals和hashCode的区别
        • [== 和 equals 的区别是什么?](https://www.cnblogs.com/sttcorcy/p/11652570.html)
        • Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
        • 指出下面程序的运行结果。
        • 什么是隐式转换,什么是显式转换
        • 接口有什么特点?
        • 接口与抽象类有什么区别?
        • 抽象类能使用 final 修饰吗?
        • Collection接口下有那些集合框架?
        • List接口有什么特点?
        • Set接口有什么特点
        • Map有什么特点
        • Java集合框架
        • java的异常
        • 需要包含 XXXXX 的封闭实例
        • Java的反射
        • 注解
        • 元注解
        • java的内存

接口的高级应用

/*接口类*/
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;  
    }  
}

工厂模式

工厂模式

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

步骤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 的实体类。
Java小记_第2张图片
步骤 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小记_第3张图片
Java小记_第4张图片

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();

Java的反射

Java高级特性——反射

反射机制的相关类

类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

获取class文件对象的几种方法

	/*方式一 
	 使用类的对象获取
	 
	 每个类都使用Object作为父类,Object类方法 getClass()
     返回这个类的class文件对象,方法返回值Class类型对象
    */
    Person person = new Person();
    Class<? extends Person> objectPerson = person.getClass();
 
    /*方式二
    使用类的静态属性获取
    
    类名.class 返回这个类的class文件对象.属性运行结果也是Class类型对象
    */
    try {
        Class<?> objectPerson = Class.forName("Person");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
 
    /*方式三
    使用Class类的静态方法获取
    
    Class类静态方法 forName(String 类名) 传递字符串类名
	获取到这个类的class文件对象,方法返回值也是Class类型对象
    */
    Class<? extends Person> objectPerson = Person.class;

注解

java注解-最通俗易懂的讲解

元注解

@Retention 注解指定了被修饰的注解的生命周期

  • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
  • RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
  • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM中,所以在程序运行时可以获取到它们。

@Target 指定了注解运用的地方。

  • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
  • ElementType.CONSTRUCTOR 可以给构造方法进行注解
  • ElementType.FIELD 可以给属性进行注解
  • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
  • ElementType.METHOD 可以给方法进行注解
  • ElementType.PACKAGE 可以给一个包进行注解
  • ElementType.PARAMETER 可以给一个方法内的参数进行注解
  • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

注解的属性
注解的属性也叫做成员变量。注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型。

注解中定义属性时它的类型必须是 8 种基本数据类型外加 类、接口、注解及它们的数组。

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int id();
    String msg();
}

上面代码定义了 TestAnnotation 这个注解中拥有 id 和 msg 两个属性。在使用的时候,我们应该给它们进行赋值。

赋值的方式是在注解的括号内以 value=”” 形式,多个属性之前用 ,隔开。

@TestAnnotation(id=3,msg="hello annotation")
public class Test {
}

注解中属性可以有默认值,默认值需要用 default 关键值指定。比如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    public int id() default -1;
    public String msg() default "Hi";
}

因为有默认值,所以无需要再在 @TestAnnotation 后面的括号里面进行赋值了。

@TestAnnotation()
public class Test {}

java的内存

栈区、堆区、静态区/方法区

  • 1、栈区:由编译知器自动分配释放,存放函数的参数值、局部变量的值等、基本类型的变量,例如int a=3中的a、对象的引用变量,例如Thread t=new Thread()中的t、具体方法执行结束之后,系统自动释放JVM内存资源。

  • 2、堆区:一般由程序员分配释放,存放由new创建的对象和数组,jvm不定时道查看这个对象,如果没有引用指向这个对象就内回收。

  • 3、静态区/方法区:存放全局变量,静态变量和字符串常量,不释放和整个应用的生命周期一样。

你可能感兴趣的:(Android学习笔记)