接口的高级应用
/*接口类*/
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 的实体类。

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