当前位置:网站首页>反射课后习题及做题记录
反射课后习题及做题记录
2022-08-02 06:23:00 【王小小鸭】
1. 写出获取Class实例的三种常见方式 获取Class类对象(实例)的三种方式 - 类名.class属性 Class<Student> c1 = Student.class; - 对象名.getClass()方法 Student s = new Student(); Class<? extends Student> c3 = s.getClass(); - Class.forName(全类名)方法 Class<?> c4 = Class.forName("com.itheima_02.Student"); 2. 谈谈你对Class类的理解 1.类的加载过程: 程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。 接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件 加载到内存中。此过程就称为类的加载。加载到内存中的类,我们就称为运行时类,此 运行时类,就作为Class的一个实例。 2.换句话说,Class的实例就对应着一个运行时类。 3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式 来获取此运行时类。
反射
反射就是把Java类中的各种成分映射成相应的java类。例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显示要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以的得到这些实例对象
3. 利用反射和重载完成以下功能
1)创建Student类,类中有属性name和age并封装属性
2)重载Student的构造函数,一个是无参构造并,另一个是带两个参数的有参构造,要求在构造函数打印提示信息
3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象
4)通过上述获取的Class对象分别调用Student有参函数和无参函数
a. 使用对象名.getClass()方法 获取class实例
打印出来的是存储地址
代码和 打印结果:
package com.B.Reflect_15.Ask_03; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException { //3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象 // a.-对象名.getClass()方法 获取class实例 Student s1 = new Student(); Class<? extends Student> c = s1.getClass(); // 此乃提示信息! //[email protected] //---------- //[email protected] // //进程已结束,退出代码 0 / // 4)通过上述获取的Class对象分别调用Student有参函数和无参函数 //调用无参函数并创建对象obj Constructor<?> constructor = c.getConstructor(); Object obj = constructor.newInstance(); //调用带参函数并创建对象obj1 Constructor<?> constructor1 = c.getConstructor(String.class, int.class); Object obj1 = constructor1.newInstance("知谓忧",22); System.out.println(obj); System.out.println("----------"); System.out.println(obj1); } }
此乃提示信息!
[email protected]
----------
[email protected]
进程已结束,退出代码 0
b.- Class.forName(全类名)方法 获取class实例
打印出来依旧是地址
package com.B.Reflect_15.Ask_03;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException {
//3)创建带main函数的NewInstanceTest类,利用Class类得到Student对象
// b.- Class.forName(全类名)方法 获取class实例
Class<?> c1 = Class.forName("com.B.Reflect_15.Ask_03.Student");
// 4)通过上述获取的Class对象分别调用Student有参函数和无参函数
//调用无参函数并创建对象obj
Constructor<?> constructor = c1.getConstructor();
Object obj = constructor.newInstance();
//调用带参函数并创建对象obj1
Constructor<?> constructor1 = c1.getConstructor(String.class, int.class);
Object obj1 = constructor1.newInstance("知谓忧",22);
System.out.println(obj);
System.out.println("----------");
System.out.println(obj1);
}
}
此乃提示信息!
[email protected]
----------
[email protected]
进程已结束,退出代码
利用通过反射修改私有成员变量
定义PrivateTest类,有私有name属性,并且属性值为hellokitty,只提供name的getName的公有方法
创建带有main方法ReflectTest的类,利用Class类得到私有的name属性
修改私有的name属性值,并调用getName()的方法打印name属性值
代码:
package com.B.Reflect_15.Ask_01;
//1. 定义PrivateTest类,有私有name属性,并且属性值为hellokitty,只提供name的getName的公有方法
public class PrivateTest {
private String name = "hellokitty";
public PrivateTest() {
}
public PrivateTest(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.B.Reflect_15.Ask_01;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
//2. 创建带有main方法ReflectTest的类,利用Class类得到私有的name属性
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//- Class.forName(全类名)方法 获取class实例对象
Class<?> c = Class.forName("com.B.Reflect_15.Ask_01.PrivateTest");
// 3. 修改私有的name属性值,并调用getName()的方法打印name属性值
//创建运行时类的对象
PrivateTest pri= (PrivateTest) c.newInstance();
//1. getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
Field name = c.getDeclaredField("name");
//2.保证当前属性是可访问的
//暴力反射,适用于私有构造方法/对象
//public void setAccessible(boolean flag):值为true,取消访问检查
name.setAccessible(true);
//3.获取、设置指定对象的此属性值
name.set(pri,"臭小子");
System.out.println(pri.getName());
}
}
2.利用反射和File完成以下功能
利用Class类的forName方法得到File类
在控制台打印File类的所有构造器
通过newInstance的方法创建File对象,并创建D:\mynew.txt文件 */
报错!
Exception in thread "main" java.lang.NoSuchMethodException: com.B.Reflect_15.Ask_03.Student.<init>(java.lang.String)
at java.base/java.lang.Class.getConstructor0(Class.java:3349)
at java.base/java.lang.Class.getConstructor(Class.java:2151)
at com.B.Reflect_15.Ask_02.FileDemo.main(FileDemo.java:24)
查看API得到 public class NoSuchMethodException extends ReflectiveOperationException
当无法找到特定方法时抛出。
最后查看资料后发现出错点在
- Class.forName(全类名)方法 获取class实例对象
这一步,类名错误,改过来就运行正确了
public java.io.File(java.lang.String,java.lang.String)
public java.io.File(java.io.File,java.lang.String)
private java.io.File(java.lang.String,java.io.File)
private java.io.File(java.lang.String,int)
public java.io.File(java.net.URI)
public java.io.File(java.lang.String)
进程已结束,退出代码 0
完整代码:
package com.B.Reflect_15.Ask_02;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//利用反射和File完成以下功能
// 1. 利用Class类的forName方法得到File类
// 2. 在控制台打印File类的所有构造器
// 3. 通过newInstance的方法创建File对象,并创建D:\mynew.txt文件
public class FileDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//- Class.forName(全类名)方法 获取class实例对象
// Class<?> cla = Class.forName("com.B.Reflect_15.Ask_03.Student");
Class cla = Class.forName("java.io.File");
//获取File的所有构造器并输出
Constructor[] con = cla.getDeclaredConstructors();
for (Constructor c : con) {
System.out.println(c);
}
//获取File的一个构造器
Constructor<?> constructor = cla.getConstructor(String.class);
//用上面得到构造器创建File对象
File file = (File) constructor.newInstance("D:\\mynew.txt");
//获取File的createNewFile方法
Method method = cla.getMethod("createNewFile");
//通过createNewFile方法,File对象,完成文件的创建
method.invoke(file);
}
}
边栏推荐
猜你喜欢
武汉高性能计算大会2022举办,高性能计算生态发展再添新动力
交换网络----三种生成树协议
Facebook社媒营销的5大技巧,迅速提高独立站转化率!
[Dataset][VOC] Male and female dataset voc format 6188 sheets
abaqus如何快速导入其他cae文件的assembly?
[npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
MySQL Advanced SQL Statements (2)
yml字符串读取时转成数字了怎么解决
HCIP 第四天
张驰课堂:六西格玛培训工具——箱线图
随机推荐
Neo4j 中文开发者月刊 - 202207期
Expert Insights | 3 ways to seize innovation opportunities in a downturn
专家见解|经济低迷期把握创新机会的 3 大方法
解决:- SPY: No data found for this date range, symbol may be delisted报错
CAT1 4G+以太网开发板腾讯云手机微信小程序显示温度和下发控制
About the local server problem after ue4.27 pixel streaming package
[数据集][VOC]男女数据集voc格式6188张
MySQL classic 50 practice questions and the most detailed analysis of the whole network
Pagoda+FastAdmin 404 Not Found
Launch Space on-premises deployment (local) Beta!
C# Coding Conventions Handbook
aTrust项目的相关操作与分享
Leetcode Weekly 304
Revitalize rural circular economy and digital chain to link agricultural "ecological chain"
The nacos source code can not find the istio package
享年94岁,图灵奖得主、计算复杂性理论先驱Juris Hartmanis逝世
MySQL - Multi-table query and case detailed explanation
Connection reset by peer 问题解析
(笔记整理未完成)【图论】图的遍历
Nodejs installation and global configuration (super detailed)