2019-2-23
说说你对 Java 中反射的理解
Java 中 的 反 射 首 先 是 能 够 获 取 到 Java 中 要 反 射 类 的 字 节 码 , 获 取 字 节 码 有 三 种 方 法 ,
1.Class.forName(className) 2.类名.class 3.this.getClass()。然后将字节码中的方法,变量,构造函数等映射成
相应的 Method、Filed、Constructor 等类,这些类提供了丰富的方法可以被我们所使用。
写一个 ArrayList 的动态代理类( 笔试题 )
1. final List<String> list = new ArrayList<String>();
2.
3. List<String> proxyInstance =
4. (List<String>)Proxy.newProxyInstance(list.getClass().getClassLoader(),
5. list.getClass().getInterfaces(),
6. new InvocationHandler() {
8. @Override
9. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10. return method.invoke(list, args);
11. }
12. });
13. proxyInstance.add("你好");
14. System.out.println(list);
静态工厂方法模式,将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
1. public class SendFactory {
2. public static Sender produceMail(){
3. return new MailSender();
4. }
5.
6. public static Sender produceSms(){
7. return new SmsSender();
8. }
9. }
10.
11.
12. public class FactoryTest {
13. public static void main(String[] args) {
14. Sender sender = SendFactory.produceMail();
15. sender.send();
16. }
17. }
抽象工厂模式
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修
改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂
类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
1. public interface Provider {
2. public Sender produce();
3. }
4. -------------------------------------------------------------------------------------
5. public interface Sender {
6. public void send();
7. }
8. -------------------------------------------------------------------------------------
9. public class MailSender implements Sender {
10.
11. @Override
12. public void send() {
13. System.out.println("this is mail sender!");
14. }
15. }
16. -------------------------------------------------------------------------------------
17. public class SmsSender implements Sender {
18.
19. @Override
20. public void send() {
21. System.out.println("this is sms sender!");
22. }
23. }
24. -------------------------------------------------------------------------------------
25. public class SendSmsFactory implements Provider {
26.
27. @Override
28. public Sender produce() {
29. return new SmsSender();
30. }
31. }
1. public class SendMailFactory implements Provider {
2.
3. @Override
4. public Sender produce() {
5. return new MailSender();
6. }
7. }
8. -------------------------------------------------------------------------------------
9. public class Test {
10. public static void main(String[] args) {
11. Provider provider = new SendMailFactory();
12. Sender sender = provider.produce();
13. sender.send();
14. }
15. }
建造者模式(Builder)
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,
所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的。
1. public class Builder {
2. private List<Sender> list = new ArrayList<Sender>();
3.
4. public void produceMailSender(int count) {
5. for (int i = 0; i < count; i++) {
6. list.add(new MailSender());
7. }
8. }
9.
10. public void produceSmsSender(int count) {
11. for (int i = 0; i < count; i++) {
12. list.add(new SmsSender());
13. }
14. }
15. }
1. public class Builder {
2. private List<Sender> list = new ArrayList<Sender>();
3.
4. public void produceMailSender(int count) {
5. for (int i = 0; i < count; i++) {
6. list.add(new MailSender());
7. }
8. }
9.
10. public void produceSmsSender(int count) {
11. for (int i = 0; i < count; i++) {
12. list.add(new SmsSender());
13. }
14. }
15. }
1. public class TestBuilder {
2. public static void main(String[] args) {
3. Builder builder = new Builder();
4. builder.produceMailSender(10);
5. }
6. }
Java 的类加载器的种类都有哪些?
1、根类加载器(Bootstrap) --C++写的 ,看不到源码
2、扩展类加载器(Extension) --加载位置 :jre\lib\ext 中
感恩于心,回报于行。 面试宝典系列-Java
http://www.itheima.com Copyright©2018 黑马程序员
303
3、系统(应用)类加载器(System\App) --加载位置 :classpath 中
4、自定义加载器(必须继承 ClassLoader)
类什么时候被初始化?
1)创建类的实例,也就是 new 一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName("com.lyj.load"))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM 启动时标明的启动类,即文件名和类名相同的那个类
只有这 6 中情况才会导致类的类的初始化。
类的初始化步骤:
1)如果这个类还没有被加载和链接,那先进行加载和链接
2)假如这个类存在直接父类,并且这个类还没有被初始化(注意:在一个类加载器中,类只能初始化一
次),那就初始化直接的父类(不适用于接口)
3)加入类中存在初始化语句(如 static 变量和 static 块),那就依次执行这些初始化语句。
排序比较器的用法
departments.sort((d1, d2) -> {
int compareLevel = d1.getDepLevel().compareTo(d2.getDepLevel());
int cpmpareTime = 0;
if (d1.getCreateTime() != null && d2.getCreateTime() != null) {
Long dd1 = (Long) (d1.getCreateTime().getTime());
Long dd2 = (Long) (d2.getCreateTime().getTime());
cpmpareTime = dd1.compareTo(dd2);
}
//如果等级相同则比较创建时间
return compareLevel == 0 ? cpmpareTime : compareLevel;
});
----------------------------------------------------
Collections.sort(distPackDetailVO.getDates(), new Comparator<MinPriceDate>() {
@Override
public int compare(MinPriceDate o1, MinPriceDate o2) {
if(o1.getDate().getTime() > o2.getDate().getTime()){
return 1;
}else if (o1.getDate().getTime() < o2.getDate().getTime()){
return -1;
}else{
return 0;
}
}
});