目录
一、注解
内置注解:JAVA中已经定义好的注解。
元注解:修饰注解的注解。
自定义注解。
二、克隆
JAVA中对clone的实现?
浅克隆
深克隆
那么该如何做到深克隆呢?
三、常用设计模式
1、创建型模式
单例模式
工厂模式
工厂方法模式
抽象工厂模式
原型模式
一、注解
java中的注解也称标注,可以用来对类、方法、属性、参数、包等进行标注。然后让编译器或运行时其他类进行解析。完成某个功能注解也可以编译到字节码文件中。
内置注解:JAVA中已经定义好的注解。
@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。@SuppressWarnings - 指示编译器去忽略注解中声明的警告。@FunctionalInterface 用于指示被修饰的接口是函数式接口。
元注解:修饰注解的注解。
@Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中,或者是在运行时可以通过反射访问。@Documented - 标记这些注解是否包含在用户文档中。@Target - 标记这个注解应该是哪种 Java 成员。@Inherited - 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何子类)@Repeatable - 标识某注解可以在同一个声明上使用多次。
自定义注解。
二、克隆
克隆分为浅克隆、深克隆。
JAVA中对clone的实现?
①实现Cloneable接口
②重写clone方法(Object类中的方法)
浅克隆
克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)
举例:
public class CloneDemo {public static void main(String[] args) throws CloneNotSupportedException {Student s1=new Student();Address address=new Address();address.setAddress("江苏");s1.setName("Mike");s1.setAge(20);s1.setAddress(address);Student s2=s1.clone();s2.setAge(21);s2.setName("Amy");address.setAddress("陕西");s2.setAddress(address);System.out.println(s1);System.out.println(s2);}
}
public class Student implements Cloneable{int age;String name;Address address;@Overrideprotected Student clone() throws CloneNotSupportedException {return (Student) super.clone();}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +", address=" + address.address +'}';}
}
public class Address {String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
运行结果
这是一个浅克隆的例子, 主函数中定义了一个叫Mike的Student对象实例,Student类中有基本类型age和name,还有引用类型Address。我们在主函数中使用了Object类中的方法clone() (重写了该方法)
@Overrideprotected Student clone() throws CloneNotSupportedException {return (Student) super.clone();}
从运行结果发现基本数据类型修改不影响被克隆的对象,但是关联对象数据被修改,克隆的和被克隆的对象都被修改了。可以证明 浅克隆的定义:克隆一个对象时,如果对象中有关联关系(has-a,把一个类当作另一个类的属性),只将关联对象的地址复制过来(只拿地址)
所以浅克隆支持引用类型成员变量的复制
并且我们发现,克隆的对象和被克隆的对象的地址不同,即使用clone()方法 会创建一个新对象,这里区别于JAVA中的引用
深克隆
克隆一个对象时,如果对象中有关联关系,将关联对象一同克隆(创建一个新的关联对象)
那么该如何做到深克隆呢?
1、连同关联对象一同克隆,逐级克隆(层级过多会比较麻烦)
public class CloneDemo {public static void main(String[] args) throws CloneNotSupportedException {Student s1=new Student();Address address=new Address();address.setAddress("江苏");s1.setName("Mike");s1.setAge(20);s1.setAddress(address);Student s2=s1.clone();s2.setAge(21);s2.setName("Amy");address.setAddress("陕西");System.out.println(s1);//Mike 20 陕西System.out.println(s2);//Amy 21 江苏}
}
public class Student implements Cloneable{int age;String name;Address address;@Overrideprotected Student clone() throws CloneNotSupportedException {Student s=(Student) super.clone();Address address=(Address)s.getAddress().clone();s.setAddress(address);return s;}
}
public class Address implements Cloneable{String address;@Overrideprotected Address clone() throws CloneNotSupportedException {return (Address) super.clone();}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
在Student类中再使用clone()方法克隆Address对象,并且在Address类中重写clone()方法。
运行结果
通过结果发现,改变了关联对象地址,克隆对象的地址并未改变,说明深克隆不支持引用类型成员变量的复制。
2、序列化(对象的输入输出流)
三、常用设计模式
1、创建型模式
用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使 用分离”。提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式。
单例模式
在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求 只能创建一个实例,这就是所谓的单例模式. 例如,Windows 中只能打开一个 任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费, 或出现各个窗口显示内容的不一致等错误。单例模式有 3 个特点: 1. 单例类只有一个实例对象; 2. 该单例对象必须由单例类自行创建; 3. 单例类对外提供一个访问该单例的全局访问点;
工厂模式
1、简单工厂:有一个工厂类负责生产某一类产品,同一类产品具备同一个抽象父类(抽象类/接口)。将创建对象与使用对象分离(Spring框架的设计思想)。简单工厂违背了开闭原则,添加一个产品就需要修改代码。子类过多,会导致工厂类庞大
以手机工厂为例:
手机接口:
public interface Phone {public void run();
}
手机工厂接口:
public interface PhoneFactory {void createPhone();
}
有两种品牌的手机:HUAWEI和IPhone
手机工厂,重写创建手机方法
public class PhoneFactory {static Phone createPhone(String name) {if (name.equals("HUAWEI")) {return (Phone) new HUAWEI();}else if(name.equals("IPhone")){return (Phone) new IPhone();}else {return null;}}
}
华为手机运行
public class HUAWEI implements Phone{@Overridepublic void run() {System.out.println("使用华为手机");}
}
iPhone手机运行
public class IPhone implements Phone{@Overridepublic void run() {System.out.println("使用苹果手机");}
}
主函数
public class Solution {public static void main(String[] args) {PhoneFactory huaweiFactory=new HUAWEIFactory();Phone huaweiPhone=new HUAWEI();huaweiPhone.run();PhoneFactory iphoneFactory=new IPhoneFactory();Phone iphonePhone=new IPhone();iphonePhone.run();}
}
运行结果:
工厂方法模式
对工厂进行抽象,一个抽象的产品对应一个抽象的工厂。一个具体的产品对应一个具体的工厂,一个具体的工厂负责生产一个具体的产品,需要扩展新产品时,只需要添加新的具体的产品类,和新的生产该产品的工厂类即可。这样就不需要修改原来的工厂,符合开闭原则。
手机接口:
public interface Phone {public void run();
}
手机工厂接口:
public interface PhoneFactory {void createPhone();
}
有两种品牌的手机:HUAWEI和IPhone
HUAWEI手机工厂
public class HUAWEIFactory implements PhoneFactory{@Overridepublic void createPhone() {new HUAWEI();}
}
iPhone手机工厂
public class IPhoneFactory implements PhoneFactory{@Overridepublic void createPhone() {new IPhone();}
}
华为手机运行
public class HUAWEI implements Phone{@Overridepublic void run() {System.out.println("使用华为手机");}
}
iPhone手机运行
public class IPhone implements Phone{@Overridepublic void run() {System.out.println("使用苹果手机");}
}
主函数
public class Solution {public static void main(String[] args) {PhoneFactory huaweiFactory=new HUAWEIFactory();Phone huaweiPhone=new HUAWEI();huaweiPhone.run();PhoneFactory iphoneFactory=new IPhoneFactory();Phone iphonePhone=new IPhone();iphonePhone.run();}
}
运行结果:
抽象工厂模式
抽象工厂时生产一系列产品(某公司的产品华为手机,华为汽车),在抽象工厂中定义生产不同的产品,具体工厂负责生产一个公司的一系列产品
定义一个抽象工厂
public interface AbstractFactory {Car getCar();Phone getPhone();
}
定义 汽车接口,手机接口
public interface Phone {void call();
}
public interface Car {void run();
}
定义产品工厂
public class RedmiFactory implements AbstractFactory{@Overridepublic Car getCar() {return new RedmiCar();}@Overridepublic Phone getPhone() {return new RedmiPhone();}
}
产品信息
public class RedmiPhone implements Phone{@Overridepublic void call() {System.out.println("红米手机,年轻人的选择");}
}
public class RedmiCar implements Car{@Overridepublic void run() {System.out.println("米家汽车,安心可靠");}
}
主函数
public class Solution {public static void main(String[] args) {AbstractFactory redmiFactory=new RedmiFactory();Car redmiCar=redmiFactory.getCar();Phone redmiPhone= redmiFactory.getPhone();redmiCar.run();redmiPhone.call();}
}
运行结果
原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能(new一个对象非常昂贵)。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式之一。