网站建设上机实验心得,如何设计中文网站,让别人做网站要注意什么6,动漫设计包括哪些内容泛型1.什么是泛型#xff1f;Java是一种强类型语言#xff0c;数据类型在编译时必须确定。如果我们想要在代码中使用不同类型的数据#xff0c;那么就需要为每种类型分别写出相应的代码。这样会导致代码冗长、重复#xff0c;也不便于维护。为了解决这个问题#xff0c;Ja…泛型1.什么是泛型Java是一种强类型语言数据类型在编译时必须确定。如果我们想要在代码中使用不同类型的数据那么就需要为每种类型分别写出相应的代码。这样会导致代码冗长、重复也不便于维护。为了解决这个问题Java引入了泛型机制允许在类、接口、方法中使用类型参数使代码更加通用、简洁、安全。示例代码// 不使用泛型
List list new ArrayList();
list.add(hello);
String str (String) list.get(0); // 需要强制类型转换容易出现类型转换异常// 使用泛型
ListString list new ArrayListString();
list.add(hello);
String str list.get(0); // 不需要强制类型转换类型安全2.泛型类如何定义使用泛型类定义的语法格式如下public class 类名类型参数列表 {// 成员变量、方法等
}其中类型参数列表是用尖括号包围起来的一组类型参数可以有多个用逗号隔开。类型参数可以在类中的任何位置使用。泛型类的实例化时需要指定类型实参。示例代码public class ClassNameT {private T value;public ClassName(T value) {this.value value;}public T getValue() {return value;}
}ClassNameInteger obj new ClassNameInteger(123);
int value obj.getValue();3.泛型接口如何定义使用泛型接口定义的语法格式如下public interface 接口名类型参数列表 {// 方法声明
}其中类型参数列表和泛型类的类型参数列表语法相同可以在接口中的任何位置使用。泛型接口的实现类需要指定类型实参。public interface InterfaceNameT {void doSomething(T parameter);
}InterfaceNameString obj new InterfaceNameString() {public void doSomething(String parameter) {System.out.println(parameter);}
};
obj.doSomething(hello);4.泛型方法如何定义使用泛型方法定义的语法格式如下修饰符 类型参数列表 返回值类型 方法名(形参列表) {// 方法体
}其中类型参数列表和泛型类、泛型接口的类型参数列表语法相同可以在方法中的任何位置使用。在方法调用时可以显式指定类型实参也可以通过参数类型推断省略类型实参。public class ClassName {public T void methodName(T parameter) {System.out.println(parameter);}
}ClassName obj new ClassName();
obj.StringmethodName(hello);5.泛型的上限和下限泛型的上限和下限是限制类型参数的边界。泛型的上限使用 extends 关键字表示类型参数必须是指定的类型或其子类。泛型的下限使用 super 关键字表示类型参数必须是指定的类型或其超类。// 上限
public class ClassName {public T extends Number void methodName(T parameter) {System.out.println(parameter);}
}ClassName obj new ClassName();
obj.methodName(123); // OK
obj.methodName(hello); // 编译错误String不是Number的子类// 下限
public void methodName(List? super Integer parameter) {parameter.add(123);parameter.add(3.14); // 编译错误3.14是double类型
}ListNumber list1 new ArrayListNumber();
methodName(list1); // OK
ListObject list2 new ArrayListObject();
methodName(list2); // 编译错误Object不是Integer或Integer的超类
6.如何理解Java中的泛型是伪泛型Java中的泛型是通过类型擦除实现的即在编译时擦除类型信息在运行时不保留类型信息。因此在运行时无法获得泛型类型参数的具体类型。这样Java中的泛型就成了一种“伪泛型”。泛型类型信息在编译时可以检查但在运行时被擦除这是泛型机制的一个局限性但也是Java泛型的一个优点因为这种方式避免了运行时的类型转换错误并提高了运行时的性能。另外Java中的泛型还存在一个“类型擦除”问题。在使用泛型时类型参数实际上被转换成了其边界类型或 Object 类型。这就导致了一些限制比如无法创建泛型数组无法在泛型类型中使用基本类型等。虽然Java中的泛型有一些限制但仍然是一种非常有用的机制可以使代码更加通用、简洁、安全。public class ClassNameT {private T value;public ClassName(T value) {this.value value;}public T getValue() {return value;}
}ClassNameInteger obj1 new ClassNameInteger(123);
ClassNameString obj2 new ClassNameString(hello);System.out.println(obj1.getClass().getName()); // ClassName
System.out.println(obj2.getClass().getName()); // ClassName// 泛型类型信息在运行时被擦除异常1.Java异常类层次结构Java异常类层次结构是异常处理的基础如下所示java.lang.Object|--java.lang.Throwable|--java.lang.Error|--java.lang.Exception|--java.io.IOException|--java.sql.SQLException|--其他异常类所有的异常类都继承自 Throwable 类。Throwable 类有两个直接子类Error 和 Exception。Error 表示系统级别的错误和资源耗尽等无法恢复的错误程序通常无法处理。例如OutOfMemoryError 表示内存不足错误。Exception 是程序中可能会遇到的异常情况程序可以通过捕获和处理这些异常来恢复正常运行。Exception 又分为可查的异常checked exceptions和不可查的异常unchecked exceptions。可查的异常是指在编译时必须进行处理的异常这些异常必须被捕获或声明抛出。不可查的异常是指在编译时无法确定是否需要处理的异常这些异常不需要被捕获或声明抛出。2.可查的异常checked exceptions和不可查的异常unchecked exceptions区别可查的异常必须在编译时进行处理否则编译器会报错。这些异常通常是由系统或程序逻辑错误引起的例如文件不存在、输入输出错误等。常见的可查异常包括 IOException、SQLException 等。不可查的异常通常是由程序设计错误引起的例如空指针异常、类型转换异常等。这些异常通常发生在运行时编译器无法检测到。不可查的异常不需要在方法签名中声明抛出并且不需要在调用时进行处理。3.throw和throws的区别throw 和 throws 关键字都用于处理异常但含义不同。throw 关键字用于抛出一个异常对象。在方法中当程序发现异常情况时可以使用 throw 关键字抛出一个异常对象。例如if (x null) {throw new NullPointerException(x is null);
}throws 关键字用于在方法签名中声明可能抛出的异常。在方法中如果可能会抛出一个异常但是不想在方法内部进行处理可以在方法签名中使用 throws 关键字声明可能抛出的异常。例如public void foo() throws Exception {// 方法体
}4.Java 7 的 try-with-resourcesJava 7 引入了 try-with-resources 语句这是一种简化关闭资源代码的方法。在 try-with-resources 语句中可以自动关闭实现了 java.lang.AutoCloseable 接口的资源例如文件或数据库连接等。以下是一个使用 try-with-resources 语句的简单示例public class Demo {public static void main(String[] args) {try (BufferedReader reader new BufferedReader(new FileReader(file.txt))) {String line reader.readLine();while (line ! null) {System.out.println(line);line reader.readLine();}} catch (IOException e) {e.printStackTrace();}}
}在上面的示例中BufferedReader 和 FileReader 都实现了 AutoCloseable 接口。在 try-with-resources 语句中我们创建一个 BufferedReader 对象和一个 FileReader 对象并将它们作为资源传递给 try 语句。当程序离开 try 块时JVM 会自动关闭这两个资源。try-with-resources 语句可以有多个资源例如try (Resource1 res1 new Resource1(); Resource2 res2 new Resource2()) {// ...
}在这种情况下两个资源都会被自动关闭。如果资源之间有依赖关系可以按照需要在 try-with-resources 语句中创建和关闭资源。5.Java 异常的底层实现,以及Exception Table是什么Java 异常的底层实现涉及到 Java 虚拟机JVM中的 Exception Table。在 Java 代码编译成字节码时编译器会将所有可能抛出异常的代码块标记为异常处理器。这些异常处理器被编译器放在 Exception Table 中并包含了异常处理器的入口地址、代码块的起始和结束位置、以及异常类型等信息。当程序执行到可能抛出异常的代码块时JVM 会检查 Exception Table 中是否存在与当前抛出的异常匹配的异常处理器。如果存在则将程序控制流转移到对应的异常处理器执行异常处理器中的代码。如果不存在匹配的异常处理器则将异常抛出到调用栈上层的异常处理器或者 JVM 运行时系统中进行处理。下面是一个简单的示例用于演示 Exception Table 的实现public class Demo {public static void main(String[] args) {int result divide(10, 0);System.out.println(Result: result);}public static int divide(int a, int b) {int result 0;try {result a / b;} catch (ArithmeticException e) {System.out.println(Exception caught: e.getMessage());}return result;}
}
在上面的示例中divide() 方法计算两个整数的商。如果除数为 0则会抛出一个 ArithmeticException 异常。在 main() 方法中调用 divide() 方法计算结果并打印计算结果。当执行到 result a / b 语句时JVM 会检查 Exception Table 中是否存在匹配 ArithmeticException 异常的异常处理器。在这个示例中存在一个匹配的异常处理器它位于 catch (ArithmeticException e) 代码块中。JVM 将程序控制流转移到异常处理器中并执行其中的代码打印异常信息。然后JVM 将程序控制流返回到调用 divide() 方法的地方继续执行程序。反射什么是反射反射是一种在运行时动态地获取类的信息和调用类的方法的能力。Java 反射 API 可以让程序在运行时动态地创建对象、访问对象属性、调用对象方法以及获取对象信息等从而增强了程序的灵活性和可扩展性。2.反射的使用反射可以用来实现一些高级的特性比如依赖注入、框架配置和代理等。反射 API 主要提供了以下几个类来实现反射功能Class 类表示一个类的类型可以用来获取类的信息、实例化对象、访问类的静态成员和调用类的方法等。Field 类表示一个类的字段可以用来访问和修改对象的属性。Method 类表示一个类的方法可以用来调用对象的方法。Constructor 类表示一个类的构造函数可以用来实例化对象。下面是一个简单的示例用于演示反射的使用public class Demo {private String message;public Demo(String message) {this.message message;}public String getMessage() {return message;}
}public class Main {public static void main(String[] args) throws Exception {Class? cls Class.forName(Demo);Constructor? constructor cls.getConstructor(String.class);Object obj constructor.newInstance(Hello, world!);Method method cls.getMethod(getMessage);String message (String) method.invoke(obj);System.out.println(message);}
}
在上面的示例中Demo 类有一个带有一个参数的构造函数和一个返回 message 属性值的 getMessage() 方法。在 Main 类中使用 Class.forName() 方法获取 Demo 类的类型然后使用 getConstructor() 方法获取 Demo 类的带有一个字符串参数的构造函数。接着使用 newInstance() 方法创建一个 Demo 类的实例。最后使用 getMethod() 方法获取 Demo 类的 getMessage() 方法然后使用 invoke() 方法调用该方法并将返回值强制转换为字符串类型。3.getName、getCanonicalName与getSimpleName的区别这三个方法都是在 Class 类中定义的可以用来获取一个类的名称或规范化名称。在很多情况下它们的返回值是相同的。但是在一些特殊情况下它们的返回值可能会有所不同。getName() 方法返回的是一个类的全限定名包括包名和类名例如 java.lang.String。getCanonicalName() 方法返回的是该类的规范化名称也就是在所有类型名称上执行一系列规则后的名称例如 java.lang.String。getSimpleName() 方法返回的是该类的简单名称也就是不包括包名的类名例如 String。