1.反射
Class 这是一个类
任何一个类,当它被加载到内存时,JVM自动创建了一个Class对象,这个Class对象像镜子一样照着当前这个类的类结构,
它可以看见当前这个类的成员变量和方法
获取当前Class对象的三种方法:
1. 类名.class
2. 对象名.getClass()
3. Class.forName(全类名)
注意:对于某个类加载而言,任何一种方式生成的Class对象实际上是同一个对象
getSimpleName() 可以通过Class对象调用该方法获取正在加载的类名
Person p = new Person ( ) ;
Class c1 = p. getClass ( ) ;
Class c2 = Person. class ;
System. out. println ( c1== c2) ;
Class c3 = null;
try {
c3 = Class. forName ( "com.iweb.test1.Person" ) ;
} catch ( ClassNotFoundException e) {
e. printStackTrace ( ) ;
}
System. out. println ( c1== c3) ;
System. out. println ( c1. getSimpleName ( ) ) ;
2.Class对象.newInstance()
我们可以通过Class对象.newInstance()来创建正在加载的那个类的对象,它其实是调用该类无参的构造方法进行创建
Class< Person> c1 = Person. class ;
try {
Person p = c1. newInstance ( ) ;
} catch ( InstantiationException e) {
e. printStackTrace ( ) ;
} catch ( IllegalAccessException e) {
e. printStackTrace ( ) ;
}
3.Field
Person p = c1. newInstance ( ) ;
Field f1 = c1. getField ( "name" ) ;
f1. set ( p, "张三" ) ;
Field f2 = c1. getDeclaredField ( "age" ) ;
f2. setAccessible ( true ) ;
f2. set ( p, 2 ) ;
4.Method
表示一个方法
1.无参方法:
通过Class对象.getMethod("方法名")来获取当前正在加载类的某个方法的Method对象
然后,通过该对象.invoke(加载类对象)来执行方法
Method m1 = c1. getMethod ( "show" ) ;
m1. invoke ( p) ;
2.有参方法:
通过Class对象.getMethod("方法名",参数类型.class)来获取当前正在加载类的某个方法的Method对象
然后,通过该对象.invoke(加载类对象,参数值)来执行方法
Method m2 = c1. getMethod ( "display" , String. class ) ;
m2. invoke ( p, "中国" ) ;
5.Field
Field[ ] fields = c1. getFields ( ) ;
System. out. println ( fields. length) ;
for ( Field field : fields) {
System. out. println ( "属性是" + field) ;
}
Field[ ] fields2 = c1. getDeclaredFields ( ) ;
for ( Field field : fields2) {
System. out. println ( "属性是" + field) ;
}
6.Method
1.getMethods()
获取所有方法包括父类的方法,返回Method数组
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println(method);
}
2.getDeclaredMethods()
获取当前类中的方法,返回Method数组
Method[] methods2 = c1.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
7.Constructor
表示一个构造方法对象,我们可以通过Class对象调用getDeclaredConstructors()获取当前类中的构造方法数组
Constructor[] constructors = c1.getDeclaredConstructors();
System.out.println(constructors.length);
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
8.单例模式
我们需要将构造方法私有化,并提供一个该类类型的成员变量使用private static修饰
1.饿汉模式:在当前类被加载的时候,自动创建出唯一对象,对于唯一的对象还需要final修饰,通过静态方法返回给调用者
2.懒汉模式:类加载的时候,不创建唯一对象,等到静态方法被第一次调用的时候,来判断成员变量是否为空,如果为空就创建
注意:饿汉模式线程同步;懒汉模式线程不同步,需要手动在静态方法上添加 synchronized 关键字
public class MySingleton {
private static final MySingleton only = new MySingleton ( ) ;
private MySingleton ( ) {
}
public static MySingleton getOnly ( ) {
return only;
}
}
public class MySingleton2 {
private static MySingleton2 only = null;
private MySingleton2 ( ) { }
public static MySingleton2 getOnly ( ) {
if ( only== null)
only = new MySingleton2 ( ) ;
return only;
}
}
9.静态代码块
当前类加载到内存时所要执行的代码
格式:
static{
}
10.工厂模式
工厂模式:将实体类的创建过程封装在工厂类中,当需要该对象时,只需要调用工厂类的静态方法返回某个对象即可
1.静态工厂模式
创建一个集合对象,作为成员变量,用来存储一些产品对象,在静态代码块中完成产品对象的生产并存入集合对象,
然后提供一个public static的工厂方法给外键调用,根据需要返回指定的产品即可。
2.实例工厂模式
首先必须创建工厂对象,然后才能完成产品的生产级返回。
public class Car {
private String cno;
private String brand;
private int price;
. . .
}
public class CarFactory {
private static Map< String, Car> map = new HashMap < > ( ) ;
static {
map. put ( "10001" , new Car ( "10001" , "audi" , 2500000 ) ) ;
map. put ( "10002" , new Car ( "10002" , "bmw" , 100000 ) ) ;
}
public static Car getCar ( String cno) {
return map. get ( cno) ;
}
}
public class Test5 {
public static void main ( String[ ] args) {
Car c = CarFactory. getCar ( "10001" ) ;
System. out. println ( c) ;
}
}
public class CarFactory2 {
private Map< String, Car> map = null;
public CarFactory2 ( ) {
map = new HashMap < > ( ) ;
map. put ( "10001" , new Car ( "10001" , "audi" , 2500000 ) ) ;
map. put ( "10002" , new Car ( "10002" , "bmw" , 100000 ) ) ;
. . .
}
public Car getCar ( String cno) {
return map. get ( cno) ;
}
}
public class Test6 {
public static void main ( String[ ] args) {
CarFactory2 carFactory2 = new CarFactory2 ( ) ;
Car car = carFactory2. getCar ( "10001" ) ;
System. out. println ( car) ;
}
}
11.代理模式
主体业务逻辑的类只专注自己的业务,周边相关的杂事交给代理类解决
我们定义一个完整业务的接口,使得主题类和代理类都实现该接口,我们定义一个完整业务的接口,使得主体类和代理类都实现该接口,
主体类在重写业务的方法中只需要专注主体业务.代理类提供主体类类型的成员变量,并且在重写的业务方法中调用主体类的业务方法,
除此之外,再完成相关的周边业务功能,用户只需要面向代理类进行业务方法调用即可。
public class CarFactory2 implements CarSale {
private Map< String, Car> map = null;
public CarFactory2 ( ) {
map = new HashMap < > ( ) ;
map. put ( "10001" , new Car ( "10001" , "audi" , 2500000 ) ) ;
map. put ( "10002" , new Car ( "10002" , "bmw" , 100000 ) ) ;
map. put ( "10003" , new Car ( "10003" , "ford" , 10000 ) ) ;
map. put ( "10004" , new Car ( "10004" , "volv" , 125500 ) ) ;
}
public Car getCar ( String cno) {
return map. get ( cno) ;
}
@Override
public void sale ( ) {
System. out. println ( "工厂卖车" ) ;
}
}
public class Car4s implements CarSale {
CarFactory2 carFactory2 = new CarFactory2 ( ) ;
@Override
public void sale ( ) {
System. out. println ( "我是4s店,我开始帮工厂卖车" ) ;
carFactory2. sale ( ) ;
System. out. println ( "上牌" ) ;
System. out. println ( "上保险" ) ;
System. out. println ( "售后" ) ;
}
}
public class Test7 {
public static void main ( String[ ] args) {
Car4s car4s = new Car4s ( ) ;
car4s. sale ( ) ;
}
}