学Java一篇文章就够了(手把手教你入门)

第11章 枚举&注解&内部类

一、枚举

概念

枚举类型是Java 5中新增特性的⼀部分,它是⼀种特殊的数据类型,之所以特殊是因为它既是⼀种类

(class)类型却⼜⽐类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性

以及便捷性。

枚举在各个语⾔当中都有着⼴泛的应⽤,通常⽤来表示诸如颜⾊、⽅式、类别、状态等等数⽬有限、形

式离散、表达⼜极为明确的量。Java从JDK5开始,引⼊了对枚举的⽀持。

为什么使用枚举

在枚举出现之前,如果想要表示⼀组特定的离散值,往往使⽤⼀些常量。例如:

public class Entity { public static final int VIDEO = 1;//视频 public static final int AUDIO = 2;//⾳频 public static final int TEXT = 3;//⽂字 public static final int IMAGE = 4;//图⽚ private int id; private int type; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getType() { return type; } public void setType(int type) { this.type = type; } }

例如,针对上述的Entity类,如果要对Entity对象的type属性进⾏赋值,⼀般会采⽤如下⽅法:

Entity e = new Entity();

e.setId(10);

//e.setType(2);

//⽽这样的话,问题⼜来了。这样做,客户端必须对这些常量去建⽴理解,才能了解如何去使⽤这个东西。

//说⽩了,在调⽤的时候,如果⽤户不到Entity类中去看看,还真不知道这个参数应该怎么传、怎

么调

e.setType(Entity.AUDIO);

缺点

(1)代码可读性差、易⽤性低。由于setType()⽅法的参数是int型的,在阅读代码的时候往往会让读者

感到⼀头雾⽔,根本不明⽩这个2到底是什么意思,代表的是什么类型。

(2)类型不安全。在⽤户去调⽤的时候,必须保证类型完全⼀致,同时取值范围也要正确。像是

setType(-1)这样的调⽤是合法的,但它并不合理,今后会为程序带来种种问题。

(3)耦合性⾼,扩展性差。假如,因为某些原因,需要修改Entity类中常量的值,那么,所有⽤到这些

常量的代码也就都需要修改——当然,要仔细地修改,万⼀漏了⼀个,那可不是开玩笑的。同时,这样

做也不利于扩展。

使用枚举

枚举(在Jave中简称为enum)是⼀个特定类型的类。所有枚举都是Java中的新类

java.lang.Enum的隐式⼦类。此类不能⼿⼯进⾏⼦类定义。⼀个简单的枚举可以是这样:

public enum TypeEnum { VIDEO,AUDIO,TEXT,IMAGE; }

上⾯的Entity类就可以改成这样:

public class Entity2 { private int id; private TypeEnum type; public int getId() { return id; } public void setId(int id) { this.id = id; } public TypeEnum getType() { return type; } public void setType(TypeEnum type) { this.type = type; } }

在为Entity对象赋值的时候,就可以这样:

Entity2 e = new Entity2(); e.setId(10); e.setType(TypeEnum.AUDIO);

在调⽤setType()时,可选值只有四个,否则会出现编译错误,因此可以看出,枚举是类型安全的,不会

出现取值范围错误的问题。同时,客户端不需要建⽴对枚举中常量值的了解,使⽤起来很⽅便,并且可

以容易地对枚举进⾏修改,⽽⽆需修改客户端。如果常量从枚举中被删除了,那么客户端将会失败并且

将会收到⼀个错误消息。

在Java中⼀个枚举就是⼀个类,它也可以有属性和⽅法,并且实现接⼝。只是所有的枚举都继承⾃

java.lang.Enum类,因此enum不可以再继承其他的类。

下⾯给出在枚举中声明属性和⽅法的示例:

public enum TypeEnum { VIDEO(1), AUDIO(2), TEXT(3), IMAGE(4); int value; TypeEnum(int value) { this.value = value; } public int getValue() { return value; } }

如果要为每个枚举值指定属性,则在枚举中必须声明⼀个参数为属性对应类型的构造⽅法(不能

是public)。否则编译器将给出The constructor TypeEnum(int, String) is undefined的错误。

在此例中,属性为int型,因此构造⽅法应当为int型。除此之外,还可以为枚举指定多个属性

枚举构造器为什么不能是public?

如果其含有public构造器,那么在类的外部就可以通过这个构造器来新建实例,显然这时实例的数量和

值就不固定了,这与定义枚举类的初衷相⽭盾,为了避免这种形象,就对枚举类的构造器默认使⽤

private修饰。如果为枚举类的构造器显式指定其它访问控制符,则会编译出错。、

public enum TypeEnum { VIDEO(1, "视频"), AUDIO(2, "⾳频"), TEXT(3, "⽂本"), IMAGE(4, "图像"); int value; String name; TypeEnum(int value, String name) { this.value = value; this.name = name; } public int getValue() { return value; } public String getName() { return name; } }

二、注解

所有注解 继承自java.lang.annotation.Annotation接口

package enum_annotation_innerclass.anno; public @interface MyAnno { //属性列表 int value(); String[] abc(); }

反编译: javap MyAnno.class

Compiled from "MyAnno.java"

public interface enum_annotation_innerclass.anno.MyAnno extends java.lang.annotation.Annotation { public abstract int value(); public abstract java.lang.String[] abc(); }

属性列表本质上是接口抽象方法

返回值必须为以下类型:

  1. 八大基本数据类型
  2. String
  3. 枚举
  4. 注解
  5. 以及以上类型的数组

使用注解时若没有默认值要赋值,若有 default则不用赋值

若只有一个属性,可以不用写属性名,直接赋值

数组时,若只有一个元素,则可以不写{}

@Target:描述注解能够作⽤的位置

ElementType 取值:

ElementType.TYPE 指定注解只能修饰类或者接⼝ --重点

ElementType.FIELD 指定注解只能修饰成员属性 --重点

ElementType.METHOD 指定注解只能修饰⽅法 --重点

ElementType.PARAMETER 指定注解只能修饰⽅法的参数

ElementType.CONSTRUCTOR 指定注解只能修饰构造⽅法

ElementType.LOCAL_VARIABLE 指定注解只能修饰局部变量

ElementType.TYPE_USE 指定注解能修饰所有的 --JDK1.8后拥有

@Retention:描述注解被保留的阶段

RetentionPolicy.SOURCE 注解信息保留在源⽂件中

RetentionPolicy.CLASS 保留在class⽂件中

RetentionPolicy.RUNTIME 注解信息在运⾏时保留,搭配反射使⽤ --重点

元注解:注解的注解

package enum_annotation_innerclass.anno; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.LOCAL_VARIABLE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PACKAGE; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.TYPE_PARAMETER; import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.CLASS; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Documented @Retention(CLASS) @Target({ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE }) /** * @author gcl15 * */ public @interface AllAnno { }

@Documented

用来生成文档

eclipse: project->Generate Javadoc->VM options设置为 -encoding UTF-8 -charset UTF-8 ->完成

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }

@Retention

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }

枚举类:public enum RetentionPolicy { //保留策略

SOURCE, //源码

CLASS, //编译期

RUNTIME //运行期

}

@Target

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }

public enum ElementType { /** 类,接口(包含注解),枚举*/ TYPE, /**字段声明,包括注解常量*/ FIELD, /** 方法声明*/ METHOD, /** 入参*/ PARAMETER, /** 构造方法*/ CONSTRUCTOR, /** 本地变量声明(方法中的局部变量))*/ LOCAL_VARIABLE, /** 注解类型声明*/ ANNOTATION_TYPE, /** 包 */ PACKAGE, /** *类型参数 */ TYPE_PARAMETER, /** */ TYPE_USE }

三、内部类

什么是内部类

可以将一个类的定义放在另一个类的内部,这就是内部类,广义上我们将内部类分为四种:成员内部类,静态内部类,局部(方法)内部类,匿名内部类。

使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个接口的实现,对于内部类都没有影响。

语法:

public class Outer{ class Inner{ } }

成员内部类

外部类、内部类

package enum_annotation_innerclass.innerclass; public class Outer { private int outerVar = 1; private int commonVar = 2; private static int outerStaticVar = 3; public void outerMethod() { System.out.println("外部类成员方法outerMethod"); } public static void outerStaticMethod() { System.out.println("外部类静态方法outerStaticMethod"); } public Inner getInstance() { Inner inner = new Inner(); return inner; } // 成员内部类 public class Inner { private int commonVar = 20; public Inner() { super(); } /** * 成员方法,访问外部类信息(属性和方法) */ public void innerShow() { System.out.println("commonVar:" + commonVar); System.out.println("外部类commonVar:" + Outer.this.commonVar); System.out.println("外部类的成员变量outerVar:" + outerVar); System.out.println("外部类的静态变量outerStaticVar:" + outerStaticVar); // 外部类的方法 outerMethod(); outerStaticMethod(); } } }

其他类使用内部类

package enum_annotation_innerclass.innerclass; public class Other { public static void main(String[] args) { // 创建成员内部类的对象和调用方法 Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); System.out.println(outer.getInstance()); inner.innerShow(); } } enum_annotation_innerclass.innerclass.Outer$Inner@7852e922 commonVar:20 外部类commonVar:2 外部类的成员变量outerVar:1 外部类的静态变量outerStaticVar:3 外部类成员方法outerMethod 外部类静态方法outerStaticMethod

小结:成员内部类当成外部类的成员信息存在

  • 可以是任何的访问修饰符
  • 外部类如何访问内部类信息,必须new之后通过.操作符访问
  • 内部类可以直接使用外部类的任何信息,如果属性或者方法发生冲突,调用 外部类.this.属性/方法

静态内部类

package enum_annotation_innerclass.innerclass; import enum_annotation_innerclass.innerclass.Outer.Inner; public class StaticOuter { private int outerVar = 1; private int commonVar = 2; private static int outerStaticVar = 3; static { System.out.println("StaticOuter静态代码块被执行了"); } public void outerMethod() { System.out.println("外部类成员方法outerMethod"); } public static void outerStaticMethod() { System.out.println("外部类静态方法outerStaticMethod"); } // 外部类如何同内部类打交道 public static void callInner() { System.out.println(StaticInner.innerStaticVar); StaticInner.innerStaticShow(); } public static class StaticInner { private int innerVar = 10; private int commonVar = 20; private static int innerStaticVar = 30; static { System.out.println("StaticInner静态代码块被执行了"); } public void innerShow() { System.out.println("innerVar:" + innerVar); System.out.println("内部的commonVar:" + commonVar); System.out.println("outerStaticVar:" + outerStaticVar); outerStaticMethod(); } public static void innerStaticShow() { /* * outerStaticMethod(); System.out.println("outerStaticVar:"+outerStaticVar); */ } } }

使用

package enum_annotation_innerclass.innerclass; import enum_annotation_innerclass.innerclass.StaticOuter.StaticInner; public class Other { public static void main(String[] args) { // 创建成员内部类的对象和调用方法 // Outer outer = new Outer(); // Outer.Inner inner = outer.new Inner(); // System.out.println(outer.getInstance()); // inner.innerShow(); //访问静态内部类的静态方法,静态内部类加载,外部类未被加载,独立存在,不依赖于外部类 StaticOuter.StaticInner.innerStaticShow(); //访问静态内部类中的成员方法 // StaticOuter.StaticInner staticInner = new StaticOuter.StaticInner(); // staticInner.innerShow(); } }

小结:和成员内部类对⽐理解(区别异同)

  • 作为静态成员属性存在,可以被任意的权限修饰符修饰。
  • 静态内部类的方法只能访问外部类的static关联的信息。
  • 利用 外部类.内部类 引用 = new 外部类.内部类(); 利用 引用.成员属性/方法 调用

Outer.Inner oi = new Outer.Inner();

oi.innerShow();

  • 访问内部类的静态信息,直接外部类.内部类.静态信息就可以了

//访问静态内部类的静态⽅法,Inner类被加载,此时外部类未被加载,独⽴存在,不依赖于外围类。

Outer.Inner.innerStaticShow();

  • 静态内部类可以独⽴存在,不依赖于其他外围类。

匿名内部类

1.定义接口

package enum_annotation_innerclass.innerclass; public interface IAnimal { public void speak(); }

2.匿名内部类使用

package enum_annotation_innerclass.innerclass; public class IAnimalTest { public static IAnimal getInnerInstance(String speak) { return new IAnimal() { @Override public void speak() { System.out.println(speak); } }; } public static void main(String[] args) { IAnimalTest.getInnerInstance("汪汪汪!!!").speak(); } }

反编译javap IAnimalTest$1.class后:

class enum_annotation_innerclass.innerclass.IAnimalTest$1 implements enum_annotation_innerclass.innerclass.IAnimal { public int aaa; enum_annotation_innerclass.innerclass.IAnimalTest$1(java.lang.String); public void speak(); }

3.小结【匿名内部类常常被⽤来重写某个或某些⽅法】

  • 匿名内部类是没有访问修饰符的。
  • 使用匿名内部类时,这个new之后的类首先是要存在的,其次我们要重写new后的类的某个或某些方法。

第12章 反射

概念

反射:将类的各个组成部分封装为其他对象,这就是反射机制。

好处:

  1. 可以在程序运行过程中,操作这些对象。
  2. 可以解耦,提高程序的可拓展性。

获取Class对象的方式

  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象。多用于配置文件,将类名定义在配置文件中,读取文件,加载类。
  2. 类名.class:通过类名的属性class获取,多用于参数的传递。
  3. 对象.getClass():getClass()方法在Object类中定义。

结论:同一个字节码文件,在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取Class对象都是同一个。

package reflect; public class Person { private int age; private String name; public int i; public Person() {} public Person(int age, String name) { super(); this.age = age; this.name = name; } public void eat() { System.out.println("eat()......"); } }

package reflect; public class ReflectDemo1 { public static void main(String[] args) throws ClassNotFoundException { // TODO Auto-generated method stub Class<?> aClass = Class.forName("reflect.Person"); System.out.println(aClass.toString()); Class<Person> personClass = Person.class; System.out.println(personClass); Person p = new Person(); Class<? extends Person> clazz = p.getClass(); System.out.println(clazz); System.out.println("(aClass == personClass)"+(aClass == personClass)); System.out.println("(personClass == clazz)"+(personClass == clazz)); } } class reflect.Person class reflect.Person class reflect.Person (aClass == personClass)true (personClass == clazz)true

Class对象的功能

获取成员变量

  • Field[] getFields() :获取所有public修饰的成员变量
  • Field getField(String name) 获取指定名称的 public修饰的成员变量
  • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
  • Field getDeclaredField(String name)获取指定的成员变量,不考虑修饰符

Field:成员变量

  1. 设置值 void set(Object obj, Object value)
  2. 获取值 get(Object obj)
  3. 忽略访问权限修饰符的安全检查(暴⼒反射) setAccessible(true)

package reflect; import java.lang.reflect.Field; public class ReflectDemo2 { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Person p = new Person(); //第一步,获取class类对象 Class<Person> personClass = Person.class; Field[] fields = personClass.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } System.out.println("-----------------------------------------"); Field i = personClass.getField("i"); i.set(p, 123); System.out.println("i的值:"+i.get(p)); System.out.println("i:"+i); System.out.println("-----------------------------------------"); Field name = personClass.getDeclaredField("name"); //忽略访问修饰符的检查 name.setAccessible(true); //设值 name.set(p,"liubowen"); //取值 System.out.println("name的值:"+name.get(p)); System.out.println("name:"+name); System.out.println("-----------------------------------------"); } }

获取构造函数

  • Constructor[] getConstructors() 获取所有的公共的构造方法
  • Constructor getConstructor(Class...parameterTypes) 获取指定的公共的构造方法
  • Constructor getDeclaredConstructor(Class...parameterTypes) 获取指定的声明的构造方法
  • Constructor[] getDeclaredConstructors() 获取所有的声明的构造方法

Constructor:构造方法

创建对象:T newInstance(Object... initargs)

如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

实例:

package reflect; public class Person { private int age; private String name; public int i; public Person() {} private Person(int age) { super(); this.age = age; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public void eat() { System.out.println("eat()......"); } @Override public String toString() { return "Person [age=" + age + ", name=" + name + ", i=" + i + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } }

package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ReflectDemo3 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // TODO Auto-generated method stub /*Constructor<?>[] getConstructors() Constructor<T> getConstructor(Class<?>...parameterTypes) Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes) Constructor<?>[] getDeclaredConstructors()*/ Class<Person> personClass = Person.class; //获取有参的构造方法 Constructor<Person> constructor = personClass.getConstructor(int.class,String.class); System.out.println(constructor); //创建对象1 Person person = constructor.newInstance(28,"博文"); System.out.println(person.toString()); //获取无参的构造方法 Constructor<Person> constructor2 = personClass.getConstructor(); System.out.println("constructor2:"+constructor2); //创建对象2 Person person2 = constructor2.newInstance(); System.out.println("person2:"+person2); //创建对象3 Person person3 = personClass.newInstance(); System.out.println("person3:"+person3); System.out.println("------------------------------------------"); //获取Constructor数组 Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors(); System.out.println(declaredConstructors.toString()); for (Constructor<?> constructor3 : declaredConstructors) { System.out.println(constructor3); } System.out.println("------------------------------------------"); //构造器暴力访问 } }

获取成员方法

  • Method[] getMethods() 获取类里面所有的public方法,包括父类里面的public方法
  • Method getMethod(String name,Class... parameterTypes) 获取指定的public方法
  • Method[] getDeclaredMethods() 获取类里面声明的所有的方法,不包括父类的方法
  • Method getDeclaredMethod(String name,Class... parameterTypes) 获取类里面声明的指定方法,不包括父类的方法

Method:方法对象

执行方法:Object invoke(Object obj, Object... args)

获取方法名称: String getName();

示例代码:

package reflect; public class Person { private int age; private String name; public int i; public Person() {} public Person(int age, String name) { super(); this.age = age; this.name = name; } private Person(int age) { super(); this.age = age; } public void eat() { System.out.println("eat()......"); } public void eat(String who) { System.out.println(who+" eat()......"); } private void eat(String who,String other) { System.out.println(who+other+" eat()......"); } @Override public String toString() { return "Person [age=" + age + ", name=" + name + ", i=" + i + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } }

package reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectDemo4 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class<Person> personClass = Person.class; //获取指定名称的方法 Method eat = personClass.getMethod("eat"); Person p = new Person(); eat.invoke(p); //获取指定名称,并且带参数的方法 Method eat2 = personClass.getMethod("eat", String.class); //执行带参数的方法 eat2.invoke(p, "lbw"); System.out.println("------------------------------------------"); //获取所有public修饰的方法 Method[] methods = personClass.getMethods(); for (Method method : methods) { System.out.println(method); // System.out.println(method.getName()); } System.out.println("------------------------------------------"); //获取类名 String name = personClass.getName(); System.out.println("类名:"+name); } }

在程序中使用和解析注解

在程序中使用 注解:获取注解中定义的属性值

  1. 获取注解定义的位置的对象(Class,Method,Field)
  2. 判断注解是否存在 isAnnotationPresent(Class)
  3. 获取指定的注解 getAnnotation(Class)
  4. 调用注解中的抽象方法获取配置的属性值

示例代码:

package reflect; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RUNTIME) public @interface MyAnno4 { int age() default 0; }

package reflect; @MyAnno4(age = 28) public class Person { private int age; private String name; public int i; public Person() {} public Person(int age, String name) { super(); this.age = age; this.name = name; } private Person(int age) { super(); this.age = age; } @MyAnno4(age = 787878) public void eat() { System.out.println("eat()......"); } public void eat(String who) { System.out.println(who+" eat()......"); } private void eat(String who,String other) { System.out.println(who+other+" eat()......"); } @Override public String toString() { return "Person [age=" + age + ", name=" + name + ", i=" + i + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } }

package reflect; import java.lang.reflect.Method; public class AnnotationDemo3 { public AnnotationDemo3() { // TODO Auto-generated constructor stub } public static void main(String[] args) throws NoSuchMethodException, SecurityException { Class<Person> personClass = Person.class; System.out.println(personClass.isAnnotationPresent(MyAnno4.class)); MyAnno4 anno4 = personClass.getAnnotation(MyAnno4.class); int age = anno4.age(); System.out.println("age:"+age); System.out.println("------------------------------------------"); Method test = personClass.getMethod("eat"); System.out.println(test.isAnnotationPresent(MyAnno4.class)); //获取方法上定义的注解 if(test.isAnnotationPresent(MyAnno4.class)) { System.out.println("est方法有定义注解"); MyAnno4 anno42 = test.getAnnotation(MyAnno4.class); int age2 = anno42.age(); System.out.println("age2:"+age2); } } }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现TTAO-Transformer-LSTM多变量回归预测&#xff0c;三角拓扑聚合…

C语言 #具有展开功能的排雷游戏

文章目录 前言 一、整个排雷游戏的思维梳理 二、整体代码分布布局 三、游戏主体逻辑实现--test.c 四、整个游戏头文件的引用以及函数的声明-- game.h 五、游戏功能的具体实现 -- game.c 六、老六版本 总结 前言 路漫漫其修远兮&#xff0c;吾将上下而求索。 一、整个排…

【OSCP系列】OSCP靶机-BTRsys-2.1(原创)

OSCP系列靶机—BTRsys-2.1 原文转载已经过授权 原文链接&#xff1a;Lusen的小窝 - 学无止尽&#xff0c;不进则退 (lusensec.github.io) 一、主机发现 二、端口扫描 1、快速扫描 2、全端口扫描 3、服务系统探测 4、漏洞探测 80端口扫到了一些目录&#xff0c;有wordpress框…

Paimon数据湖详解(第49天)

系列文章目录 一. Paimon数据湖增删改查 二. 查询优化 三. 系统表 四. Lookup Joins 文章目录 系列文章目录前言Paimon数据湖的使用1、创建Table1.1 创建catalog管理的表1.2 分区表1.3 Create Table As&#xff08;了解&#xff09;1.4 Create Table Like1.5 表属性1.6 创建外…

无心剑中译莎士比亚《爱如星辰引迷舟》

莎士比亚十四行诗第116首 Sonnet 116 爱如星辰引迷舟 Let me not to the marriage of true minds Admit impediments. Love is not love Which alters when it alteration finds, Or bends with the remover to remove: O, no! it is an ever-fixed mark That looks on tempe…

C++(week14): C++提高:(一)面向对象设计:设计原则、设计模式

文章目录 一、面向对象设计的概念4.统一建模语言&#xff1a;UML语言StartUML 二、类与类之间的关系0.总结(1)类与类的五种关系(2)区别(3)面向对象 vs 基于对象 1.继承 (泛化耦合)2.组合 (Composition)3.聚合 (Aggregation)4.关联(1)双向关联(2)单向关联 5.依赖 (Dependency) 三…

简单几步,把浏览器书签转换成导航网页

废话不多说直奔主题上干货 Step 1 下载浏览器书签 1&#xff0c;电脑浏览器点击下载Pintree Pintree 是一个开源项目&#xff0c;旨在将浏览器书签导出成导航网站。通过简单的几步操作&#xff0c;就可以将你的书签转换成一个美观且易用的导航页面。 2. 安装 Pintree B…

【保姆级讲解下QT6.3】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【人工智能 | 机器学习 | 理论篇】线性模型

文章目录 1. 基本形式2. 线性回归3. 对数几率回归4. 线性判别分析5. 多分类学习6. 类别不平衡问题 1. 基本形式 设有 d 个属性描述的示例 x ( x 1 , x 2 , x 3 , . . . , x d ) x ({x_1, x_2, x_3, ..., x_d}) x(x1​,x2​,x3​,...,xd​) 线性模型&#xff08;linear mode…

每天一个设计模式之命令模式(第二天)

交互模式中的命令模式&#xff0c;在开始记录之前&#xff0c;要讲些自己的感受&#xff0c;真真切切的感受到了悟性的瓶颈&#xff01;一共十页书&#xff0c;需要自己细细琢磨品味&#xff0c;至少三四遍才大概了解了他们间的逻辑&#xff0c;我需要调整下自己的学习思路&…

快速写一个Makefile

本文主要展示Makefile的基本要素和示例&#xff0c;让读者可以快速写出一个实用的Makefile。 简要说明 Makefile&#xff0c;GNU make命令工具。 书写格式 <target> : <prerequisites> [tab] <commands> <target> 文件名或某操作的名字&#xff0…

uniapp开发精选短视频视频小程序实战笔记20240725,实现顶部轮播图和热门短剧

创建项目 创建项目,叫video_app。 在pages.json里面修改一下标题: 新建search搜索页面和me我的页面。 此时界面预览效果如下: 引入静态资源 主要是static里面的内容,全部复制过来。 配置底部导航栏 pages.json,放到顶层,和全部样式同级: "tabBar&quo…

详细分析 Sql Server查询卡顿的排查方向

目录 前言1. 问题所示2. 原理分析2.1 缺乏索引2.2 表碎片2.3 查询计划缓存2.4 锁和阻塞 3. 总结 前言 本篇为理论知识的分析以及对症下药&#xff0c;前阵子发生过Bug&#xff0c;后通过迁移服务器以及数据库最终才解决问题&#xff0c;但是细想当时可能是因为碎片或者缓存的概…

WEBKIT 通过JavaScript 调用本地,硬件未来之窗OS硬件APP

以酒店为例我们需要调用shen份证读取&#xff0c;采集人脸&#xff0c;门锁写房卡&#xff0c;如何通过浏览器调用 1.通过本地http服务 2.通过webkit模式 这里说政务单位模式的集成 由于篇幅问题&#xff0c;怎么集成webkit就不说了 一、webkkit加载交互本地代码 browser.…

23、Python之面向对象:实例属性、类属性,傻傻分不清楚

引言 在上一篇文章中&#xff0c;我们初步介绍了Python面向对象中类定义的语法&#xff0c;顺带介绍了关于面向对象的系统工程中&#xff0c;所涉及的OOA与OOD。 其实&#xff0c;简单来说&#xff0c;类的定义其实就是面向对象的“封装”特性的体现。我们将分析、设计得到的…

BLE自适应跳频算法详解

前言 &#xff08;1&#xff09;自适应跳频算法是相当的简单&#xff0c;小学生都能够看懂&#xff0c;而且网上已经有相当多的关于自适应跳频算法的介绍。既然如此&#xff0c;为什么我还要写这样一篇博客呢&#xff1f; &#xff08;2&#xff09;原因很简单&#xff0c;我发…

内网横向——利用WMI进行内网横向

文章目录 一、WMI介绍二、常规利用方法三、常见利用工具3.1 wmiexec3.2 Invoke-WmiCommand 四、WMI事件订阅的利用4.1 手动实现4.2 Sharp-WMIEvent 网络拓扑&#xff1a; 攻击机kali IP&#xff1a;192.168.111.0 跳板机win7 IP&#xff1a;192.168.111.128&#xff0c;192.168…

业务记录:处理动态表头的CSV/EXCEL文件

业务描述&#xff1a;传入一个动态表头的CSV文件&#xff0c;解析CSV&#xff0c;并保存入库。 CSV文件的表头是不确定的&#xff0c;即顺序和字段个数不确定&#xff0c;以及表头是中文字段。 例如&#xff1a; 为了顺利解析CSV文件&#xff0c;前端需要传入对应的字段名和顺…

axure制作切换栏--动态面板的应用

先看下效果&#xff1a;点击上面的切换栏 切换到西游记栏目&#xff1a; 切换到水浒传栏目&#xff1a; 上述两个图片比对可以发现&#xff0c;在点击切换栏的时候&#xff0c;里面的内容以及切换栏的下面蓝色横线也会发生对应的变化。这里涉及到两个地方的变化&#xff0c;就…

Golang 知识结构图

总结Go的入门知识结构&#xff0c;如下图所示&#xff1a;