java 学习记录(Day11)

一、反射

1.定义:

反射(Reflection)是一种强大的机制,在程序运行期间,可以动态获取类中定义的属性和方法以及构造方法的机制(思想)的实现。

反射的核心是Class类 程序中使用的类,每一个都有一个唯一对应的Class对象

反射的API:Field Method Constructor

反射会破坏类的封装性 通过场景说明

(1)在java中存储了类的内容,这个内容也应该是一个对象

(2)java中每一个类都有一个内存,每一块内存都是一个对象

(3)这些对象记录了这些类中声明了那些属性和方法以及构造方法

(4)java将这类抽象为一个Class类

2.获取类的类对象

Class类的对象是不能new的

(1)通过类名获取类对象

Class clazz= EasyClassA.class;

(2)通过对象来获取:类对象

clazz =new EasyClassA().getClass();

(3)通过Class方法的forName方法获取

clazz=Class.forName("com.easy725.Easy");
类的类对象中存储了类中定义的内容  属性、方法、构造方法

3.获取类中的属性

(1)java中用来记录类的属性的类 叫做Field

Field fName= c.getField("name");
fName变量指向的对象是Easy类中的name属性

新建一个Easy类的实例,然后定义easy对象的name属性为“张三”,声明一个Object类的对象来接收Easy类的对象的name属性值,代码如下:

 Easy easy=new Easy();
        easy.name="张三";
        System.out.println(easy.name);
        //可以获取某一个Easy类的对象的name属性的值
        Object objectName=fName.get(easy);
        System.out.println(objectName+"------");

(2)注入该属性的值set(类,属性名)

fName.set(easy,"李四");
System.out.println(easy.name);
getField getFields 只能获取类中public声明的属性

反射访问受保护的属性时需要使用getDeclaredField(属性名);

Field fCode=c.getDeclaredField("code");

反射访问私有属性,必须先获取访问权限

fAddress.setAccessible(true);
fAddress.set(easy,"青岛");

System.out.println(fAddress.get(easy));
getFields() 获取所有属性

下面是Easy类的声明:

package com.easy726;

public class Easy {
    public String name;
    protected String code;
    String sex;
    private String address;
    static int maxage;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public static int getMaxage() {
        return maxage;
    }

    public static void setMaxage(int maxage) {
        Easy.maxage = maxage;
    }

    public static final transient String test=null;
    public Easy(){

    }
    public Easy(String name){
        this.name=name;
    }
    public void methodA(){
        System.out.println("methodA");
    }
    public void methodB(int a,int b){
        System.out.println("methodB");
        System.out.println("两个参数分别为"+a+","+b);
    }
}

反射的示例:

首先定义一个Student类,里面定义了code、name和sex属性,还有重写的toString方法。在测试方法中,使用泛型来确保参数和返回值类型是Class类,参数是Class类和Map类型的对象,首先创建对象通过反射类获取类中定义的属性,然后将属性名作为key,来查找Map中对应的value值,设置一个Object类对象来存储键值对,设置访问权限,将键值对注入新建的对象实例。主函数设置了Map类中的键值对。

package com.easy726;

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 InstantiationException, IllegalAccessException {
        //通过反射获取实列  创建对象
       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","C1001");
        map.put("name","宣行琮");
        map.put("sex","男");
        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 + '\'' +
                '}';
    }
}

4.获取类中的方法 Method

Method ma=c.getMethod("methodA");

无参

调用该方法 method.invoke(对象)

ma.invoke(easy);
Method mb=c.getMethod("methodB",int.class,int.class);

mb.invoke(easy,23,45);

有参

类对象都是前面的Easy类。

5.获取构造方法Constructor

获取无参的构造方法

Constructor<Easy> con= c.getConstructor();

获取有参的构造方法

con=c.getConstructor(String.class);

创建一个实例并将name属性设置为宣行琮

con.newInstance("宣行琮");

有参的构造方法

6.修饰符

使用modifier的方法判断方法、属性、构造方法的修饰符

Field f=c.getDeclaredField("test");
int fmod=f.getModifiers();
boolean bool=Modifier.isStatic(fmod);
System.out.println(bool);

判断是否使用static修饰

二、内省

也是通过反射来实现的  不会破坏封装性

(1)获取BeanInfo

BeanInfo bi= Introspector.getBeanInfo(c);

(2)获取属性的写的方法和读的方法 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方法

(3)使用写方法

Easy easy=c.newInstance();
write.invoke(easy,"zhangsan");

三、HTML

显示在页面上的内容都要写在标签body内

1.会显示在窗口 标签title

<title>页面标题</title>

2.标题,标签h1--h6

<h1>凉州词</h1>

<h2>凉州词</h2>

3.段落 标签p

<p>葡萄美酒夜光杯,欲饮琵琶马上催</p>
<p>醉卧沙场君莫笑,古来征战几人回</p>

4.图片显示  标签 img 

 <img src="./image/kui.jpg" alt="失败了"/>

alt中是图片加载失败后,显示的文本

失败的话

5.超链接 标签a

<a href="https://www.baidu.com">连接到百度</a>

 <a href="easy1.html"><img src="./image/kui.jpg" alt="失败了"/></a>

点击文字和图片都能跳转,标签a中设置要跳转网页的地址

6.表格  标签table  tr行  td列

<table>
            <tr>
                <td>编号</td>
                <td>姓名</td>
                <td>成绩</td>
            </tr>
            <tr>
                <td>1001</td>
                <td>张三</td>
                <td>100</td>
            </tr>
        </table>

设置出了两行三列的表格

也可以使用colspan和rowspan来合并单元格

colspan合并行,rowspan合并列、

建立一个4*4的表格

<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>

7.列表

(1)有序列表 标签 ol  有序号

<ol>
            <li>苹果</li>
            <li>香蕉</li>
            <li>橘子</li>
        </ol>

(2)无序列表 标签 ul  无序号

<ul>
            <li>苹果</li>
            <li>香蕉</li>
            <li>橘子</li>
        </ul>

8.表单 form

<form action="提交表单的地址" method="提交的方式get/post">

表单中的组件

(1)输入框input

<input type="text" name="username" value="宣行琮"/>

name在窗口会显示,value值是页面加载后的初始值

(2)密码框 password

将type设为password

<input type="password" name="userpass" />

(3)只读

设置readonly 就不可修改

<input type="text" readonly value="21120501152" name="code"/>

(4)隐藏域hidden

将type设置为hidden,就不会出现在页面上

(5)单选框radio

在一个表单内,name值一样的就会有互斥性

<input checked type="radio" value="M" name="sex" id="sexman"/><label for="sexman">男</label>
            <input type="radio" value="W" name="sex" id="sexwoman"/><label for="sexwoman">女</label>

在label标签中设置for,当点到文字时也能选择上

checked 初始化时的选项

(6选框checkbox

display不可选

<div>
                <input checked 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>

(7)下拉框 标签select 选项option

<div>
                <label for="province">省份</label>
                <select name="province" id="province">
                    <option>山东省</option>
                    <option value="ahs">安徽省</option>
                    <option value="xj">新疆</option>
                    <option value="sxs" selected>陕西省</option>
                    <option value="yns">云南省</option>
                </select>
            </div>

(8)文本域textarea

多行文本框 两个标签中的内容就是他的值  注意不要回车

<div>
                <!-- 文本域  多行文本框 两个标签中的内容就是他的值  注意不要回车-->
                <textarea></textarea>
            </div>

(9)按钮

<!-- 提交按钮 -->
            <button type="submit">提交按钮</button>
            <!-- 普通按钮 -->
            <button type="button">普通按钮</button>
            <!-- 重置按钮 -->
            <button type="reset">重置按钮</button>
            <input type="button" value="普通按钮Input">
            <input type="submit" value="提交按钮Input">
            <input type="reset" value="重置按钮Input">

可以使用button也可以使用input

9.样式

在style中设置

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            /*内部样式 */
            /* 样式选择器 */
            /* ID选择器 */
            #boxA{
                height: 100px;
                width: 100px;
                background-color: skyblue;
                /* 字体颜色 */
                color: green;
                font-size: 30px;
                text-align: center;
                /* 单行文本 垂直居中 行高等于容器的高度*/
                line-height: 100px;
                font-weight: 600;
                /* font-weight: bold;字体加粗 */
            }
            /* 标签选择器 元素选择器 */
            div{
                height: 100px;
                width: 100px;
            }
            /* 类选择器 class='bgred'*/
            .bgred{
                background-color: red; 
                /* 不显示 */
                display: none;
            }
        </style>
    </head>
    <body>
        <!--内联样式  -->
        <div style="width: 100px;height: 100px;background-color: deeppink;"></div>
        <div id="boxA">你好</div>
        <div class='bgred'></div>
        <div class='bgred'></div>
    </body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值