Java初学笔记(三):异常与反射

12 篇文章 0 订阅

异常处理

  1. throws在方法体前声明此方法可能抛出的异常

  2. throw在方法体内执行抛出异常对象

  3. 异常捕获处理

    try {}
    catch{}
    finally{}
    
  4. catch块和finally块同时有return或throw语句时, finally块会覆盖catch的return和throw

  5. catch块内语句执行完才会跳转到finally块

  6. 自定义异常, 通常是从RuntimeException派生业务根异常BaseException, 然后再派生具体的业务异常

    public class BaseException extends RuntimeException {
     	public BaseException() {
       	 	super();
    	}
    	public BaseException(String message, Throwable cause) {
       	 	super(message, cause);
    	}
    	public BaseException(String message) {
        	super(message);
    	}
    	public BaseException(Throwable cause) {
        	super(cause);
    	}
    	// 提供多种构造方法
    }
    public class UserNotFoundException extends BaseException {
    }
    public class LoginFailedException extends BaseException {
    }
    

反射

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;

Class类

  1. class是由JVM在执行过程中动态加载的。JVM在第一次读取到一种class类型时,将其加载进内存。

  2. 每加载一种class,JVM就为其创建一个Class类型的实例,并关联起来

  3. 一个Class实例包含了该class的所有完整信息

  4. 通过Class实例获取class信息的方法称为反射(Reflection)

    // 通过类的静态变量class获取
    Class cls1 = String.class;
    // 通过实例变量的getClass方法获取
    Class cls2 = "abcd".getClass();
    // 利用一个类的完整类名, 通过静态方法Class.forName()获取
    Class cls3 = Class.forName("java.lang.String");
    
  5. Class实例在JVM中是唯一的, 所以可以用==比较两个Class实例

  6. Class实例比较与instanceOf的区别:

    Integer n = new Integer(123);
    
    boolean b1 = n instanceof Integer;
    // true,因为n是Integer类型
    boolean b2 = n instanceof Number;
    // true,因为n是Number类型的子类
    
    boolean b3 = n.getClass() == Integer.class;
    // true,因为n.getClass()返回Integer.class
    boolean b4 = n.getClass() == Number.class;
    // false,因为Integer.class!=Number.class
    
  7. 对象实例转型后并不会改变其关联的class信息

  8. cls.getName(), 完整类名

  9. cls.getSimpleName(), 简单类名

  10. cls.getPackage().getName(), 包名

  11. cls.isInterface(), 是否接口

  12. cls.isEnum(), 是否枚举

  13. cls.isArray(), 是否数组

  14. cls.isPrimitive(), 是否基本类型

  15. 注意: 数组也有Class, 而且不同于其基础类型的Class

  16. 基本类型也有Class

Class类实例方法

访问字段
  1. Field getField(name):根据字段名获取某个public的field(包括父类)
  2. Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
  3. Field[] getFields():获取所有public的field(包括父类)
  4. Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
Field对象方法
  1. getName():返回字段名称,例如,“name”;

  2. getType():返回字段类型,也是一个Class实例,例如,String.class;

  3. getModifiers():返回字段的修饰符,它是一个int,不同的bit表示不同的含义。

  4. 利用反射获取字段信息:

    Field f = String.class.getDeclaredField("value");
    f.getName();    // "value"
    f.getType();    // class [B 表示byte[]类型
    int m = f.getModifiers();
    Modifier.isFinal(m);    // true
    Modifier.isPublic(m);   // false
    Modifier.isProtected(m);    // false
    Modifier.isPrivate(m);  // true
    Modifier.isStatic(m);   // false
    
  5. 获取对象的字段值f.get(Object)

  6. private字段会报错, 使用f.setAccessible(true)可以开放权限再获取, 但也可能失败(有安全管理)

  7. 设置对象的字段值f.set(Object,Object), 与get类似

调用方法
  1. Method getMethod(name, Class...):获取某个public的Method(包括父类)
  2. Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
  3. Method[] getMethods():获取所有public的Method(包括父类)
  4. Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
Method对象方法
  1. getName():返回方法名称,例如:“getScore”;
  2. getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class;
  3. getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class};
  4. getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。
  5. invoke(Object, ...args): 使用参数调用对象的该方法
  6. 静态方法调用invoke(null, ...args)
  7. 调用非public方法: Method.setAccessible(true)先开放权限
多态

使用反射调用方法时,仍然遵循多态原则:即总是调用实际类型的覆写方法(如果存在)

调用构造方法
  1. getConstructor(Class...):获取某个public的Constructor
  2. getDeclaredConstructor(Class...):获取某个Constructor
  3. getConstructors():获取所有public的Constructor
  4. getDeclaredConstructors():获取所有Constructor
  5. 注意: Constructor总是当前类定义的构造方法, 和父类无关, 因此不存在多态的问题
  6. 调用非public的Constructor时,必须首先通过setAccessible(true)设置允许访问, 可能会失败
获取继承关系
  1. 获取父类Class

    Class i = Integer.class;
    Class n = i.getSuperclass();
    Class o = n.getSuperclass();
    o.getSuperclass();  // null
    
  2. 获取interface

    Class[] is = Integer.class.getInterfaces();
    
  3. 注意: getInterfaces()只返回当前类直接实现的接口类型,并不包括其父类实现的接口类型

  4. 对所有interfaceClass调用getSuperclass()返回的是null,获取接口的父接口要用getInterfaces()

  5. 如果一个类没有实现任何interface,那么getInterfaces()返回空数组

  6. 判断继承关系

    Integer.class.isAssignableFrom(Number.class);   // false
    Number.class.isAssignableFrom(Integer.class);   // true
    
动态代理

在运行期动态创建一个interface实例

  1. 定义一个InvocationHandler实例,它负责实现接口的方法调用;
  2. 通过Proxy.newProxyInstance()创建interface实例,它需要3个参数:
    • 使用的ClassLoader,通常就是接口类的ClassLoader
    • 需要实现的接口数组,至少需要传入一个接口进去;
    • 用来处理接口方法调用的InvocationHandler实例。
  3. 将返回的Object强制转型为接口。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
    public static void main(String[] args) {
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
            Hello.class.getClassLoader(), 	// 传入ClassLoader
            new Class[] { Hello.class }, 	// 传入要实现的接口
            handler); 						// 传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }
}

interface Hello {
    void morning(String name);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Web开发教程: 入门与提高篇(JSP Servlet)PDF》是一本针对Java Web开发的教程,旨在帮助读者从入门到提高掌握JSP和Servlet的使用。 这本教程包括两个主要部分:JSP和Servlet。JSP(Java Server Pages)是一种动态网页开发技术,它允许开发人员在HTML网页上嵌入Java代码。Servlet是一种运行在服务器端的Java程序,用于处理客户端请求和生成响应。 在入门部分,教程首先介绍了Java Web开发的基础知识,包括HTML和CSS的基本语法、HTTP协议的工作原理等。然后,它详细介绍了JSP的语法和标签,包括如何在JSP页面中嵌入Java代码,如何使用JSTL(JSP标准标签库)等。同时,它还介绍了如何使用Eclipse等常用的开发工具来编写和调试JSP页面。 在提高部分,教程进一步深入讲解了Servlet的使用。它介绍了Servlet的生命周期、请求处理过程和Servlet API的常用类和方法。此外,教程还介绍了如何使用Cookie和Session来实现用户认证和数据共享,以及如何使用过滤器和监听器来实现请求过滤和监听事件。 该教程的特点是通俗易懂,结合实例和练习,帮助读者进行实践。此外,教程还提供了一些实际项目案例,帮助读者理解和应用所学知识。 总之,《Java Web开发教程: 入门与提高篇(JSP Servlet)PDF》是一本适合Java Web开发初学者和有一定基础的开发人员学习的教材,通过学习该教程,读者可以全面掌握JSP和Servlet的使用,为自己的Web开发之路做好铺垫。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值