赞
踩
1. 反射
反射是指在运行时检查、获取和修改类的属性、方法、构造方法等信息的能力,可以在运行时动态地创建对象、调用方法、访问属性,而不需要在编译时确定。
2. 获取类对象的三种方式
在代码中展示了三种获取类对象(Class对象)的方法:
通过类名获取类对象:
Class clazz = EasyClassA.class;这种方式直接使用类名后跟 .class 来获取对应的 Class 对象。
通过对象获取类对象:
clazz = new EasyClassA().getClass();通过创建类的实例,然后调用 getClass() 方法来获取其对应的 Class 对象。
通过 Class.forName() 方法获取:
clazz = Class.forName("com.easy725.EasyColor");使用类的全限定名(包括包名)作为参数,调用 Class.forName() 方法来动态获取该类的 Class 对象。
3. Class 类对象的作用
Class 类对象包含了与类相关的信息,如属性、方法、构造方法等的定义。Class类的对象是不能new的。反射的核心是Class类,程序中使用的类,每一个都有一个唯一对应的Class对象。
在运行时,Java 使用 Class 对象来表示和管理类的结构和元数据,允许在运行时检查和操作类。
- package com.easy726;
-
- public class EasyClassA {
- //反射
- //有对象之前必须先有类,static来修饰类的属性和方法。
- //在java中存储了类的内容,这个内容也应该是一个对象。
- //java中每一个类都有一个内存,这每一块内存都是一个对象。
- //这些对象用来记录类中声明了哪些属性和方法以及构造方法。
- //java将这些类抽象为一个Class类。
- public static void main(String[] args) throws ClassNotFoundException {
- //Class类的对象是不能new的
- //获取类的类对象
- //1.通过类名获取类对象
- Class clazz=EasyClassA.class;
- //2.通过对象获取类对象
- clazz=new EasyClassA().getClass();
- //3.通过Class方法的forName方法获取
- clazz=Class.forName("com.easy725.EasyColor");
- System.out.println(clazz);
- //类的类对象中存储了类中定义的内容,属性/方法/构造方法。
-
- }
- }
获取和设置属性值:Field
getField("name") 可以获取 Easy 类中名为 name 的公共属性,并且可以通过 fName.get(easy) 获取 easy 对象的 name 属性的值。
getDeclaredField("code") 可以获取 Easy 类中名为 code 的任意访问控制修饰符的属性(包括私有属性),但是在访问私有属性前需要调用 setAccessible(true) 设置访问权限。
注意事项:
getField 和 getFields 只能获取公共的字段(即使用 public 修饰的字段),而 getDeclaredField 和 getDeclaredFields 则可以获取类中声明的所有字段,不论其访问控制符是什么。对于私有字段,必须通过 setAccessible(true) 来解除访问限制。
- package com.easy726;
-
- import java.lang.reflect.Field;
- import java.util.HashMap;
-
- public class EasyClassB {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
- //类的类对象中存储了类中定义的内容(属性/方法/构造方法)。
- Class c=Easy.class;
- c=new Easy().getClass();
- c=Class.forName("com.easy726.Easy");
- //获取内容
- //1.获取类中的属性
- //java中用来记录类的属性的类叫做Filed。
- //fName指向的对象就是Easy类中的name属性。
- Field fName=c.getField("name");
- Easy easy=new Easy();
- easy.name="张三";
- System.out.println(easy.name);
- //可以获取某一个Easy类的对象的name属性的值
- Object objectName=fName.get(easy);
- System.out.println(objectName+"---");
- //注入该属性的值
- fName.set(easy,"李四");
- System.out.println(easy.name);
- //getField和getFields只能获取类中的public声明的属性
- Field fCode=c.getDeclaredField("code");
- fCode.set(easy,"10001");//设置code属性的值
- Object objCode=fCode.get(easy);//通过反射获取easy对象的code属性的值
- System.out.println(objCode);
- Field fSex=c.getDeclaredField("sex");
- Field fAddress=c.getDeclaredField("address");
- fSex.set(easy,"女");
- //反射访问私有属性,必须先获取访问权限。
- fAddress.setAccessible(true);
- fAddress.set(easy,"青岛");
- System.out.println(fAddress.get(easy));
-
- //getFields()
-
- }
- }
getInstance 方法:
getInstance 方法利用反射创建一个指定类的对象,并根据传入的 values 参数设置对象的属性值。
Class.newInstance() 方法通过调用目标类的无参构造方法来实例化对象。
设置属性访问权限:
破坏类的封装性:
反射可以访问和修改类中私有的字段,这可能会破坏类的封装性,因为它允许绕过类的设计意图直接访问私有数据成员。
- package com.easy726;
-
- import java.lang.reflect.Array;
- import java.lang.reflect.Field;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.Map;
-
- public class EasyClassC {
- //反射:在程序运行期间,可以动态获取类中定义的属性和方法以及构造方法的机制(思想)的实现
- //反射的核心是Class类,程序中使用的类,每一个都有一个唯一对应的Class对象
- //反射的API:Field,Method,Constructor
- //反射会破坏类的封装性,通过场景说明
- public static <T> T getInstance(Class<T> tClass, Map values) throws IllegalAccessException, InstantiationException {
- //通过反射来获取实例,创建对象
- T t=tClass.newInstance();//通过类中的无参构造方法,创建对象。
- //通过反射获取类中定义的属性
- Field[] farr=tClass.getDeclaredFields();
- //System.out.println(Arrays.toString(farr));
- for (Field fitem:farr){
- //获取属性的名字
- String fname=fitem.getName();//获取属性的名字
- //获取该属性在Map中的键值对(属性对应的值)
- Object value=values.get(fname);
- //设置属性访问权限
- fitem.setAccessible(true);
- fitem.set(t,value);
- }
- return t;
- }
-
- public static void main(String[] args) throws InstantiationException, IllegalAccessException {
- Map map=new HashMap<>();
- map.put("code","C10001");
- map.put("name","张三");
- map.put("esx","女");
- Student stu=getInstance(Student.class,map);
- System.out.println(stu);
- }
- }
- class Student{
- private String code;
- private String name;
- private String sex;
-
- @Override
- public String toString() {
- return "Student{" +
- "code='" + code + '\'' +
- ", name='" + name + '\'' +
- ", sex='" + sex + '\'' +
- '}';
- }
- }
获取方法对象:Method
Method ma = c.getMethod("methodA"); 使用 getMethod() 方法获取了 Easy 类中的名为"methodA" 的公共方法对象 ma。这里 "methodA" 是方法的名称,没有参数。
调用方法:
ma.invoke(easy); 通过 invoke() 方法调用了 easy 对象的 methodA() 方法。invoke() 方法允许在运行时动态地调用方法,即使不知道方法的具体名称和参数。
获取带参数的方法:
Method mb = c.getMethod("methodB", int.class, int.class); 使用 getMethod() 方法获取了 Easy 类中的名为 "methodB",且接受两个 int 类型参数的方法对象 mb。
调用带参数的方法:
mb.invoke(easy, 23, 45); 通过 invoke() 方法调用了 easy 对象的 methodB(int a, int b) 方法,传入了参数 23 和 45。这里的 mb 是 Method 对象,它可以动态调用 easy 对象的方法并传递参数。
- package com.easy726;
-
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
-
- public class EasyClassD {
- public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
- //获取类对象
- Class<Easy> c=Easy.class;
- //反射获取方法 Method
- Easy easy=c.newInstance();
- //获取public方法
- Method ma=c.getMethod("methodA");
- //调用方法
- //对象.方法名() 面向对象
- //method.invoke(对象) 反射的写法
- ma.invoke(easy);
- Method mb=c.getMethod("methodB", int.class, int.class);
- mb.invoke(easy,23,45);
-
- }
- }
获取构造方法:Constructor
Class<Easy> c = Easy.class;Constructor<Easy> con = c.getConstructor(String.class);
通过 Class 对象获取类的构造方法,然后利用构造方法对象创建类的实例。
实例化对象:
con.newInstance("张三");使用获取到的构造方法对象调用 newInstance 方法来创建类的实例。
修饰符:使用Modifier的方法判断方法/属性/构造方法的修饰符。
获取属性的修饰符:
Field f = c.getDeclaredField("test");int fmod = f.getModifiers();
Boolean bool = Modifier.isStatic(fmod);
通过 Field 对象获取属性的修饰符,然后使用 Modifier.isStatic 方法判断属性是否为静态。
内省:
内省是一种通过反射来获取类的属性、方法等信息,但不会破坏类的封装性,主要用于获取和设置属性的读写方法。
获取属性的读写方法:
使用 Introspector.getBeanInfo 方法获取类的 BeanInfo,然后通过 PropertyDescriptor 获取属性的读写方法。
调用属性的setter方法:
Easy easy = c.newInstance();write.invoke(easy, "zhangsan");
使用反射调用 setter 方法设置属性的值。
- package com.easy726;
-
- import java.beans.BeanInfo;
- import java.beans.IntrospectionException;
- import java.beans.Introspector;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.*;
- import java.util.Arrays;
-
- public class EasyClassE {
- public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, IntrospectionException {
- //反射获取构造方法
- Class<Easy> c=Easy.class;
- c.newInstance();//调用无参构造方法
- Constructor<Easy> con=c.getConstructor();//获取无参构造方法
- con.newInstance();
- con=c.getConstructor(String.class);
- con.newInstance("张三");
-
- //修饰符,使用Modifier的方法判断方法/属性/构造方法的修饰符
- Field f=c.getDeclaredField("test");
- int fmod=f.getModifiers();
- Boolean bool=Modifier.isStatic(fmod);
- System.out.println(bool);
-
- //内省,也是通过反射来实现的,但是内省不会破坏封装性。
- //内省获取属性的读方法和写方法来获取和设置属性的内容,不会破坏类的封装性。
- //获取BeanInfo
- BeanInfo bi=Introspector.getBeanInfo(c);
- //获取属性的写的方法和读的方法(setter和getter)
- PropertyDescriptor[] pds=bi.getPropertyDescriptors();
- System.out.println(Arrays.toString(pds));
- String pName=pds[0].getName();//获取属性名字
- System.out.println("属性名是:"+pName);
- Method read=pds[0].getReadMethod();//对应属性的getter方法
- Method write=pds[0].getWriteMethod();//对应属性的setter方法
- //obj.setName("zhangsan");//面向对象
- //write.invoke(obj,"zhangsan");//反射
- Easy easy=c.newInstance();
- write.invoke(easy,"zhangsan");
-
- }
- }
文档类型声明
<!DOCTYPE html>定义了HTML文档类型,告诉浏览器这是一个HTML5文档。
HTML结构
<html>: HTML文档的根元素。
<head>: 包含了文档的元数据,如字符编码声明、标题和样式表。
<meta charset="utf-8">: 声明文档使用UTF-8字符编码,确保中文等非ASCII字符能正常显示。
<title>: 定义文档标题,显示在浏览器的标签页标题栏中。
<style>: 内部样式表,定义了表格和表格单元格的样式。
标题和段落
<h1>, <h2>: 定义标题,1级和2级标题。
<p>: 定义段落,包含文本内容。
图片和超链接
<img>: 插入图片,src属性指定图片路径,alt属性定义图片加载失败时的替代文本。
<a>: 创建超链接,href属性指定链接目标。
表格
<table>: 创建表格。
<tr>: 表格行。
<td>: 表格数据单元格。
colspan(合并列)和rowspan(合并行): 合并单元格。
列表
<ol>: 有序列表。
<ul>: 无序列表。
<li>: 列表项。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>页面标题</title>
- <style>
- table,td{
- border:1px solid deeppink;
- border-collapse: collapse;
- }
- td{
- width: 70px;
- text-align: center;
- padding: 10px;
- }
- </style>
- </head>
- <body>
- <!--标题 h1-h6 -->
- <h1>凉州词</h1>
- <h2>凉州词</h2>
- <!--段落-->
- <p>葡萄美酒夜光杯,欲饮琵琶马上催。</p>
- <!--图片-->
- <!-- .代表当前路径 ..代表上一级路径-->
- <img src="./image/easyimg.png" alt="加载失败" />
- <!-- 超链接-->
- <a href="https://www.baidu.com">链接到百度</a>
- <a href="easy.html">
- <img src="./image/easyimg.png" alt="加载失败" />
- </a>
-
- <table>
- <tr>
- <td>编号</td>
- <td>姓名</td>
- <td>成绩</td>
- </tr>
- <tr>
- <td>1001</td>
- <td>张三</td>
- <td>100</td>
- </tr>
- </table>
- <table>
- <tr>
- <td>1-1</td>
- <td colspan="2">1-2</td>
- <!-- <td>1-3</td> -->
- <td>1-4</td>
- </tr>
- <tr>
- <td rowspan="2">2-1</td>
- <td>2-2</td>
- <td>2-3</td>
- <td>2-4</td>
- </tr>
- <tr>
- <!-- <td>3-1</td> -->
- <td>3-2</td>
- <td rowspan="2" colspan="2">3-3</td>
- <!-- <td>3-4</td> -->
- </tr>
- <tr>
- <td>4-1</td>
- <td>4-2</td>
- <!-- <td>4-3</td>
- <td>4-4</td> -->
- </tr>
- </table>
- <!-- 列表 -->
- <!-- 有序列表(ol)和无序列表(ul)(有无序号) -->
- <ol>
- <li>苹果</li>
- <li>香蕉</li>
- <li>橘子</li>
- </ol>
- <ul>
- <li>苹果</li>
- <li>香蕉</li>
- <li>橘子</li>
- </ul>
- </body>
- </html>
表单基础:
<form> 标签定义了一个表单,用于收集用户输入的数据,action 属性指定了表单提交的地址,method 属性指定了提交方式,可以是 get 或 post。
文本输入框:
<input type="text" name="username"/> 定义了一个文本输入框,用于用户输入用户名。
密码输入框:
<input type="password" name="userpassword"/> 定义了一个密码输入框,输入的内容会被隐藏显示。
隐藏域:
<input type="hidden" value="10001" name="id"/> 定义了一个隐藏域,用于存储不希望用户看到或修改的数据,如记录用户ID等。
只读文本框:
<input type="text" readonly value="202111050441" name="code"/> 定义了一个只读文本框,用户不能编辑其内容,仅用于显示。
单选框:
<input type="radio" value="Man" name="sex" id="sexman"/><label for="sexman">男</label> 定义了两个单选框,分别用于选择性别,通过 name 属性实现单选的互斥选择。
复选框:
<input type="checkbox" name="hobby" id="sing" value="sing"/><label for="sing">唱</label> 定义了多个复选框,用户可以选择一个或多个选项,通过 name 属性实现多选。
下拉框:
<select name="province" id="province"> 定义了一个下拉框,用户可以从预定义的选项中选择一个省份。
文本域:
<textarea name="description" id="description" cols="30" rows="10"></textarea> 定义了一个多行文本输入框,用户可以输入多行文本。
按钮:
<button type="submit">提交按钮</button> 是一个提交按钮,用户点击后会提交表单数据。
<button type="button">普通按钮</button> 是一个普通的按钮,不会触发表单提交。
<button type="reset">重置按钮</button> 是一个重置按钮,点击后会将表单中的内容重置为初始状态。
普通按钮(使用 input 标签):
<input type="button" value="普通按钮input"/> 也是一个普通的按钮,类似于上面的 <button> 元素,但使用了 <input> 标签。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title></title>
- </head>
- <body>
- <form action="提交表单的地址" method="提交方式get/post">
- <!-- 表单中的组件 -->
- <input type="text" name="username"/>
- <!-- 密码框 -->
- <input type="password" name="userpassword"/>
- <!-- 隐藏域 -->
- <input type="hidden" value="10001" name="id"/>
- <!-- 单选框 -->
- <!-- readonly只读 -->
- <input type="text" readonly value="202111050441" name="code"/>
-
- <!-- checked默认选中(互斥可覆盖) -->
- <div>
- <input checked type="radio" value="Man" name="sex" id="sexman"/><label for="sexman">男</label>
- <input type="radio" value="Woman" name="sex" id="sexwoman"/><label for="sexwoman">女</label>
- </div>
- <!-- 复选框 -->
- <!-- disable无法选中 -->
- <div>
- <input type="checkbox" name="hobby" id="sing" value="sing"/><label for="sing">唱</label>
- <input disabled type="checkbox" name="hobby" id="dance" value="dance"/><label for="dance">跳</label>
- <input type="checkbox" name="hobby" id="rap" value="rap"/><label for="rap">rap</label>
- </div>
- <!-- 下拉框 -->
- <!-- selected默认选中 -->
- <div>
- <label for="province">省份</label>
- <select name="province" id="province">
- <option value="sds">山东省</option>
- <option value="ahs">安徽省</option>
- <option value="xj" selected>新疆</option>
- <option value="sxs">陕西省</option>
- <option value="yns">云南省</option>
- </select>
- </div>
- <!-- 多行输入框(文本域) 两个标签中的内容就是他的值 注意不要回车-->
- <div>
- <textarea name="" id="" cols="30" rows="10"></textarea>
- </div>
- <button type="submit">提交按钮</button>
- <button type="button">普通按钮</button>
- <button type="reset">重置按钮</button>
- <input type="button" value="普通按钮input"/>
- </form>
- </body>
- </html>
内部样式:
CSS样式定义了几种选择器:
#boxA: ID选择器,应用于id为boxA的元素,设置了宽度、高度、背景颜色、字体颜色等样式。
div: 标签选择器,应用于所有<div>元素,设置了宽度和高度。
.bgred: 类选择器,应用于所有类名为bgred的元素,设置了背景颜色为红色并隐藏(display: none;)。
内联样式和元素:
内联样式:直接在元素上使用style属性设置样式,例如第一个<div>的样式设置了宽度、高度和背景颜色。
ID选择器应用:第二个<div>使用了ID选择器#boxA,应用了预定义的样式。
类选择器应用:后面两个<div>使用了类选择器.bgred,共享类样式,设置了背景颜色为红色并隐藏。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title></title>
- <style>
- /* 内部样式 */
- /* 选择器 */
- /* ID选择器 */
- #boxA{
- width: 100px;
- height: 100px;
- background-color: black;
- /* 字体颜色 */
- color: aqua;
- /* 文本大小 */
- font-size: 20px;
- text-align: center;
- /* 单行文本垂直居中 行高等于容器的高度 */
- line-height:100px;
- /* 字体加粗 */
- font-weight: bold;
- }
- /* 标签选择器(元素选择器) */
- div{
- width: 100px;
- height: 100px;
- }
- /* 类选择器 class='bgred'*/
- .bgred{
- background-color: red;
- display: none;
- }
- </style>
- </head>
- <body>
- <!-- 内联样式 -->
- <div style="width: 100px;height: 100px;background-color:peru"></div>
- <div id="boxA">Hellow</div>
- <div class="bgred"></div>
- <div class="bgred"></div>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。