Java基础进阶01-类加载器,反射

发布时间:2024年01月24日

目录

一、类加载器

1.概述

2.过程

(1)类加载时机

(2)类加载过程

加载

验证

准备

解析

初始化

3.分类

(1)启动类加载器(Bootstrap ClassLoader):虚拟机内置的类加载器,底层是c++,最顶层

(2)平台类加载器(Platform Classloader):负责加载JDK中一些特殊的模块

(3)系统类加载器(System Classloader):负责加载用户类路径上所指定的类库,也称为应用程序类加载器

(4)自定义类加载器(这是自定的,用的不多)

4.双亲委派模型

5.常用方法

二、反射

1.概述

2.作用

3.反射的操作

(1)获取Class对象

(2)class对象的内部结构

(3)Class类中的常用方法

(4)获取Constructor对象

(5)Constructor类常用方法

(6)利用其构造对象创建User对象

(7)Filed类中常用方法

(8)通过反射获取成员变量

(9)Method类的常用方法

(10)通过反射获取成员方法并运行


一、类加载器

1.概述

类加载器:负责将.class文件(存储的物理文件)加载在到内存中

2.过程

(1)类加载时机

类在什么时候会被加载到内存中?

  • 创建类的实例(对象)

  • 调用类的类方法(静态方法)

  • 访问类/接口的类变量,或者为该类变量赋值(静态变量)

  • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

  • 初始化某个类的子类

  • 直接使用java.exe命令来运行某个主类

总结:用到就加载,不用不加载

(2)类加载过程
  • 加载:

  • 验证:

  • 准备

  • 解析

  • 初始化

加载
  • 通过一个类的全限定名来获取此类的二进制字节流(通过包名+类名【全限定名】,获取这个类,准备用流进行传输)

  • 将这个字节流所代表的静态存储结构转化为运行时数据结构(通过上步得到的流,将其字节码文件加载到内存中)

  • 在内存中生成一个代表这个类的java.lang.Class对象(类加载到内存之后,虚拟机会创建一个该类的class对象来存储类中对应的内容)

任何类被使用时,系统都会为之建立一个java.lang.Class对象

验证
  • 确保Class文件字节流中包含的信息符合当前虚拟机的要求,且不会危害虚拟机本身(检查文件中的信息是否符合虚拟机的规范,有没有安全隐患)

准备
  • 负责为类的类变量(static修饰的变量)分配内存,并设置默认初始化值(初始化静态变量)

解析
  • 将类的二进制数据流中的符号引用替换为直接引用(如果本类中用到了其他的类,此时需要找到其对应的类)

初始化
  • 根据程序员通过程序制定的主观计划去初始化类变量和其他资源(静态变量赋值以及初始化其他资源)

3.分类

(1)启动类加载器(Bootstrap ClassLoader):虚拟机内置的类加载器,底层是c++,最顶层
(2)平台类加载器(Platform Classloader):负责加载JDK中一些特殊的模块
(3)系统类加载器(System Classloader):负责加载用户类路径上所指定的类库,也称为应用程序类加载器
(4)自定义类加载器(这是自定的,用的不多)

4.双亲委派模型

类加载器之间的层次关系,称之为类加载器的双亲委派模型

在这个模型当中,要求除了顶层的启动类加载器之外,其余的类加载器都应该有自己的父类加载器

这里的父子关系是逻辑上的继承,如想用自定义类加载器加载一个字节码文件,首先,它不会自己去尝试加载,而是将加载任务委派给其父类加载器去完成

一直委托到最顶层,这些加载器都有其各自的加载范围,当父类加载器无法完成这个加载请求的时候,它就会一层一层的往下返回,直到返回到能完成加载

的类加载器中,完成加载请求

//获取系统类加载器
classLoader systemclassLoader = classLoader.getSystemclassLoader():
//获取系统类加载器的父加载器,平台类加载器
ClassLoader classLoader1 = systemClassLoader.getParent();
//获取平台类加载器的父加载器 --- 启动类加载器
ClassLoader classLoader2 = classLoader1.getparent();
system.out.println("系统类加载器+ systemClassLoader);
system.out.printIn("平台类加载器”+ classLoader1);
System.out.printIn("系统类加载器”+ classLoader2);

5.常用方法

方法名说明
static ClassLoader getSystemClassLoader()获取系统类加载器
InputStream getResourceAsStream(String name)加载某一个资源文件 参数:文件路径 返回值:字节流对象

二、反射

1.概述

Java反射机制:

  • 是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法

  • 对于任意一个对象都能够调用它的任意属性和方法;

  • 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制

Java反射机制(简洁说明):

  • 无视修饰符获取类里面所有的属性和方法先获取配置文件中的信息

  • 动态获取信息并创建对象和调用方法

2.作用

普通方式创建对象

  • 无法访问私有属性和方法

用反射创建对象

  • 反射调用私有属性:能无视权限修饰符

  • 反射调用私有方法:能无视权限修饰符

总结:利用反射调用它类中的属性和方法时,能无视修饰符

举例:

如果用户有1个需求,并调用其特定方法

接收到程序后又更改需求n次

普通方式:

创建对象1,写其特有方法,get,set,构造,toString,在主方法中创建对象1,调用对象1的方法,再将代码打包发送,之后接收到第一次需求更改消息

创建对象2,写其特有方法,get,set,构造,toString,在主方法中删除对象1和其方法调用,重新创建对象2,调用对象2的方法,再将代码打包发送,之后接收到第二次需求更改消息

创建对象3,写其特有方法,get,set,构造,toString,在主方法中删除对象2和其方法调用,重新创建对象3,调用对象3的方法,再将代码打包发送,之后接收到第三次需求更改消息

...

创建对象n,写其特有方法,get,set,构造,toString,在主方法中删除对象,n-1和其方法调用,重新创建对象n,调用对象n的方法,再将代码打包发送,之后接收到第N次需求更改消息

总结:不灵活,需求更改要改代码

反射方式:动态获取信息,动态调用对象方法

会先将用户所有可能的需求全部过一遍,然后创建n个对象

创建对象1,写好特定方法,get,set,构造,toString,

创建对象2,写好特定方法,get,set,构造,toString,

创建对象3,写好特定方法,get,set,构造,toString,

...

创建对象n,写好特定方法

然后写一个配置文件

配置文件:

  • 要创建对象的全类名(全限定名)

  • 要调用的方法名

在主方法中读取配置文件的信息,读到什么就创建什么对象,读到什么方法就调用什么方法

用户更改需求时,不需要更改主方法中的代码,修改配置文件即可

总结:灵活

3.反射的操作

利用class对象来创建的

(1)获取Class对象
  • 加载前(源代码阶段):用Class的静态方法forName(String 全类名)

  • 已经进入到内存中(Class对象阶段):直接类名.class即可

  • 已经手动创建对象时new 对象名(运行时阶段):对象.getClass()

public class User {
 ? ?private String name;
 ? ?private Integer age;
?
 ? ?public User() {
 ?  }
?
 ? ?public User(String name, Integer age) {
 ? ? ? ?this.name = name;
 ? ? ? ?this.age = age;
 ?  }
?
 ? ?public String getName() {
 ? ? ? ?return name;
 ?  }
?
 ? ?public void setName(String name) {
 ? ? ? ?this.name = name;
 ?  }
?
 ? ?public Integer getAge() {
 ? ? ? ?return age;
 ?  }
?
 ? ?public void setAge(Integer age) {
 ? ? ? ?this.age = age;
 ?  }
?
 ? ?private void run(){
 ? ? ? ?System.out.println("User is running");
 ?  }
 ? ?@Override
 ? ?public String toString() {
 ? ? ? ?return "User{" +
 ? ? ? ? ? ? ? ?"name='" + name + '\'' +
 ? ? ? ? ? ? ? ?", age=" + age +
 ? ? ? ? ? ? ? ?'}';
 ?  }
}
public class Reflection01 {
 ? ?public static void main(String[] args) {
 ? ? ? ?//第一种
 ? ? ? ?Class userClass1 = null;
 ? ? ? ?Class userClass2 = null;
 ? ? ? ?Class userClass3 = null;
 ? ? ? ?try {
 ? ? ? ? ?userClass1 = Class.forName("reflection.User");
 ? ? ? ? ?System.out.println(userClass1);
 ? ? ?  } catch (ClassNotFoundException e) {
 ? ? ? ? ? ?e.printStackTrace();
 ? ? ?  }
?
 ? ? ? ?//第二种
 ? ? ? ?userClass2 = User.class;
 ? ? ? ?System.out.println(userClass2);
?
 ? ? ? ?//第三种
 ? ? ? ?userClass3 ?= new User().getClass();
 ? ? ? ?System.out.println(userClass3);
 ? ? ? ?
        //检查
 ? ? ? ?System.out.println(userClass1 == userClass2);
 ? ? ? ?System.out.println(userClass1 == userClass3);
 ? ? ? ?System.out.println(userClass2 == userClass3);
?
 ?  }
}

(2)class对象的内部结构

(3)Class类中的常用方法
方法名返回值类型说明
getConstructors()Constructor<?>[]返回一个包含 Constructor对象的数组, Constructor对象反映了由该 class对象表示的类的所有公共构造函数
getDeclaredConstructors()Constructor<?>[]返回反映由该 class对象表示的类声明的所有构造函数的 constructor对象的数组。
getConstructor(Class<?> ... parameterTypes)Constructor< T >返回一个 constructor对象,该对象反映由该 class对象表示的类的指定公共构造函数。
getDeclaredConstructor(Class<?> ... parameterTypes)Constructor< T >返回一个 Constructor对象,该对象反映由此 class对象表示的类或接口的指定构造函数。
getFields()Field[ ]返回所有公共成员变量对象的数组
getDeclaredFields()Field[ ]返回所有成员变量对象的数组
getField(String name)Field返回单个公共成员变量对象
getDeclaredField(String name)Field返回单个成员变量对象
getMethods()Method[ ]返回所有公共成员方法对象的数组,包括继承的
getDeclaredMethods()Method[ ]返回所有成员方法对象的数组,不包括继承的
getMethod(String name, Class<?>... parameterTypes)Method返回单个公共成员方法对象
getDeclaredMethod(String name, Class<?>... parameterTypes)Method返回单个成员方法对象

(4)获取Constructor对象

User对象

public class User {
 ? ?private String name;
 ? ?private Integer age;
 ? ?public Long id;
?
?
?
 ? ?public User() {
 ?  }
?
 ? ?public User(String name, Integer age) {
 ? ? ? ?this.name = name;
 ? ? ? ?this.age = age;
 ?  }
?
 ? ?private User(String name){
 ? ? ? ?this.name = name;
 ?  }
?
 ? ?public User(String name, Integer age, Long id) {
 ? ? ? ?this.name = name;
 ? ? ? ?this.age = age;
 ? ? ? ?this.id = id;
 ?  }
?
 ? ?public String getName() {
 ? ? ? ?return name;
 ?  }
?
 ? ?public void setName(String name) {
 ? ? ? ?this.name = name;
 ?  }
?
 ? ?public Integer getAge() {
 ? ? ? ?return age;
 ?  }
?
 ? ?public void setAge(Integer age) {
 ? ? ? ?this.age = age;
 ?  }
?
 ? ?public Long getId() {
 ? ? ? ?return id;
 ?  }
?
 ? ?public void setId(Long id) {
 ? ? ? ?this.id = id;
 ?  }
?
 ? ?private void run(){
 ? ? ? ?System.out.println("User is running");
 ?  }
 ? ?private void run(String name,Long id){
 ? ? ? ?System.out.println("id为"+id+"的用户:"+name+" is running");
 ?  }
 ? ?private String run(String name,Long id,Integer age){
 ? ? ? ?return "id为"+id+"的用户:"+name+"年龄:"+age+" is running";
 ?  }
?
 ? ?public void work(){
 ? ? ? ?System.out.println("User is working");
 ?  }
 ? ?public void work(String name){
 ? ? ? ?System.out.println(name + " is working");
 ?  }
?
 ? ?public String work(String name,Long id){
 ? ? ? ?return "id为"+id+"的用户:"+name+" is working";
 ?  }
?
 ? ?@Override
 ? ?public String toString() {
 ? ? ? ?return "User{" +
 ? ? ? ? ? ? ? ?"name='" + name + '\'' +
 ? ? ? ? ? ? ? ?", age=" + age +
 ? ? ? ? ? ? ? ?", id=" + id +
 ? ? ? ? ? ? ? ?'}';
 ?  }
}
?

测试:

public class Reflection02 {
 ? ?public static void main(String[] args) {
 ? ? ? ?Class<User> userClass = User.class;
 ? ? ? ?Constructor<?>[] constructors01 = userClass.getConstructors();
?
 ? ? ? ?for (int i = 0; i < constructors01.length; i++) {
 ? ? ? ? ? ?System.out.println(constructors01[i]);
 ? ? ?  }
 ? ? ? ?System.out.println("----------------------------------------------------");

 ? ? ? ?Constructor<?>[] constructors02 = userClass.getDeclaredConstructors();
 ? ? ? ?for (int i = 0; i < constructors02.length; i++) {
 ? ? ? ? ? ?System.out.println(constructors02[i]);
 ? ? ?  }
 ?  }
}

(5)Constructor类常用方法
方法名返回值类型说明
T newInstance(Object... initargs)创建出来的对象根据指定的构造方法创建对象

(6)利用其构造对象创建User对象
public class Reflection03 {
 ? ?public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?//利用有参构造创建User对象
 ? ? ? ?method01();
 ? ? ? ?//利用无参构造创建User对象
 ? ? ? ?method02();
?
 ? ? ? ?//空参简写
 ? ? ? ?method03();
?
 ? ? ? ?//利用私有构造创建User对象,(暴力反射)
 ? ? ? ?method04();
 ?  }
?
 ? ?private static void method04() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?Class<?> userClass = Class.forName("reflection.User");
 ? ? ? ?final Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(String.class);
 ? ? ? ?//被private修饰的是不能直接使用的
 ? ? ? ?//如果用反射强行获取需要临时取消访问检查
 ? ? ? ?declaredConstructor.setAccessible(true);
 ? ? ? ?User user = (User) declaredConstructor.newInstance("san");
 ? ? ? ?System.out.println(user);
 ?  }
?
 ? ?private static void method03() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
 ? ? ? ?Class<?> userClass = Class.forName("reflection.User");
 ? ? ? ?//在Class类中,有一个newInstance方法,可以利用空参直接创建对象
 ? ? ? ?//此方法已过时,替换为getDeclaredConstructor().newInstance()
 ? ? ? ?User user1 = (User)userClass.newInstance();
 ? ? ? ?User user2 = (User)userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?System.out.println(user1);
 ? ? ? ?System.out.println(user2);
?
 ?  }
?
 ? ?private static void method02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?Class<?> userClass = Class.forName("reflection.User");
 ? ? ? ?Constructor<?> constructor = userClass.getConstructor();
 ? ? ? ?User user1 = (User) constructor.newInstance();
 ? ? ? ?System.out.println(user1);
 ?  }
?
 ? ?private static void method01() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
 ? ? ? ?Class<?> userClass = Class.forName("reflection.User");
 ? ? ? ?Constructor<?> constructor = userClass.getConstructor(String.class, Integer.class);
?
 ? ? ? ?User user2 = (User) constructor.newInstance("小明", 29);
?
 ? ? ? ?System.out.println(user2);
 ?  }
}

(7)Filed类中常用方法
方法名返回值类型说明
set(Object object,Object value)void给指定对象的成员变量赋值
get(Object obj)Object返回指定对象的Field的值

(8)通过反射获取成员变量

  • 获取class对象

  • 获得Field对象

  • 赋值或获取值

public class Reflection04 {
 ? ?public static void main(String[] args) throws NoSuchFieldException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
 ? ? ? ?Class<User> userClass = User.class;
// ? ? ?  method01(userClass);
// ? ? ?  method02(userClass);
// ? ? ?  method03(userClass);
// ? ? ?  method04(userClass);
// ? ? ?  method05(userClass);
 ? ? ? ?method06(userClass);
?
?
 ?  }
?
 ? ?private static void method06(Class<User> userClass) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?Field name = userClass.getDeclaredField("name");
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?//取消访问检查
 ? ? ? ?name.setAccessible(true);
 ? ? ? ?//更改值
 ? ? ? ?name.set(user,"小明");
 ? ? ? ?//获取值
 ? ? ? ?Object o = name.get(user);
?
?
 ? ? ? ?System.out.println(user);
 ? ? ? ?System.out.println(o);
 ?  }
?
 ? ?private static void method05(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
 ? ? ? ?Field id = userClass.getDeclaredField("id");
?
 ? ? ? ?//利用set方法赋值
 ? ? ? ?//先创建一个User对象
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?//获得对象之后就可以赋值
 ? ? ? ?id.set(user,1000L);
 ? ? ? ?System.out.println(user);
?
 ?  }
?
 ? ?private static void method04(Class<User> userClass) throws NoSuchFieldException {
 ? ? ? ?final Field name = userClass.getDeclaredField("name");
 ? ? ? ?System.out.println(name);
 ?  }
?
 ? ?private static void method03(Class<User> userClass) throws NoSuchFieldException {
 ? ? ? ?//想要获取到的成员变量必须是真实存在的,且必须是public修饰的
 ? ? ? ?Field id = userClass.getField("id");
?
 ? ? ? ?System.out.println(id);
 ?  }
?
 ? ?private static void method02(Class<?> userClass) {
 ? ? ? ?for (Field declaredField : userClass.getDeclaredFields()) {
 ? ? ? ? ? ?System.out.println(declaredField);
 ? ? ?  }
 ?  }
?
 ? ?private static void method01(Class<?> userClass) {
?
 ? ? ? ?Field[] fields = userClass.getFields();
 ? ? ? ?for (Field field : fields) {
 ? ? ? ? ? ?System.out.println(field);
 ? ? ?  }
 ?  }
}

(9)Method类的常用方法
方法名返回值类型说明
invoke(Object o,Object... args) 参数一:用o对象调用该方法 参数二:调用方法的传递的参数(如果没有就不用写)Object在具有指定参数的指定对象上调用此 方法对象表示的基础方法。 调用方法

(10)通过反射获取成员方法并运行

  • 获取class对象

  • 获取Method对象

  • 运行方法

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
?
public class Reflection05 {
 ? ?public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?Class<User> userClass = User.class;
 ? ? ? ?//获取所有公共成员方法
 ? ? ? ?method01(userClass);
 ? ? ? ?System.out.println("--------------------------------");
 ? ? ? ?//获取所有成员方法(包括继承的)
 ? ? ? ?method02(userClass);
 ? ? ? ?System.out.println("--------------------------------");
 ? ? ? ?//获取单个公开成员方法
 ? ? ? ?method03(userClass);
 ? ? ? ?//获取单个成员方法
 ? ? ? ?method04(userClass);
?
?
?
 ? ? ? ?//运行成员方法
 ? ? ? ?//运行公开成员方法(无参无返回值)
 ? ? ? ?method05(userClass);
 ? ? ? ?//运行公开成员方法(有参无返回值)
 ? ? ? ?method06(userClass);
 ? ? ? ?//运行成员方法(无参无返回值)
 ? ? ? ?method07(userClass);
 ? ? ? ?//运行成员方法(有参无返回值)
 ? ? ? ?method08(userClass);
 ? ? ? ?//运行公开成员方法(有返回值)
 ? ? ? ?method09(userClass);
?
 ? ? ? ?//运行成员方法(有返回值)
 ? ? ? ?method10(userClass);
?
?
 ?  }
?
 ? ?private static void method10(Class<User> userClass) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method run = userClass.getDeclaredMethod("run", String.class, Long.class, Integer.class);
 ? ? ? ?run.setAccessible(true);
 ? ? ? ?String invoke = (String) run.invoke(user, "小王", 201L,10);
 ? ? ? ?System.out.println(invoke);
 ?  }
?
 ? ?private static void method09(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method work = userClass.getMethod("work", String.class, Long.class);
 ? ? ? ?work.setAccessible(true);
 ? ? ? ?String invoke = (String) work.invoke(user, "小王", 200L);
 ? ? ? ?System.out.println(invoke);
 ?  }
?
 ? ?private static void method08(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method run = userClass.getDeclaredMethod("run",String.class,Long.class);
 ? ? ? ?run.setAccessible(true);
 ? ? ? ?run.invoke(user,"小王",200L);
 ?  }
?
 ? ?private static void method07(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method run = userClass.getDeclaredMethod("run");
 ? ? ? ?run.setAccessible(true);
 ? ? ? ?run.invoke(user);
 ?  }
?
 ? ?private static void method06(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method work = userClass.getMethod("work",String.class);
 ? ? ? ?work.invoke(user,"小明");
 ?  }
?
 ? ?private static void method05(Class<User> userClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 ? ? ? ?User user = userClass.getDeclaredConstructor().newInstance();
 ? ? ? ?Method work = userClass.getMethod("work");
 ? ? ? ?work.invoke(user);
 ?  }
?
 ? ?private static void method04(Class<User> userClass) throws NoSuchMethodException {
 ? ? ? ?Method run = userClass.getDeclaredMethod("run", String.class, Long.class);
 ? ? ? ?System.out.println(run);
 ?  }
?
 ? ?private static void method03(Class<User> userClass) throws NoSuchMethodException {
 ? ? ? ?Method work = userClass.getMethod("work");
 ? ? ? ?System.out.println(work);
 ?  }
?
 ? ?private static void method02(Class<User> userClass) {
 ? ? ? ?Method[] declaredMethods = userClass.getDeclaredMethods();
 ? ? ? ?for (Method declaredMethod : declaredMethods) {
 ? ? ? ? ? ?System.out.println(declaredMethod);
 ? ? ?  }
 ?  }
?
 ? ?private static void method01(Class<User> userClass) {
 ? ? ? ?Method[] methods = userClass.getMethods();
 ? ? ? ?for (Method method : methods) {
 ? ? ? ? ? ?System.out.println(method);
 ? ? ?  }
 ?  }
?
}

文章来源:https://blog.csdn.net/qq_33627452/article/details/135784992
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。