我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ASP.NET Page该怎么理解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ASP.NET Page该怎么理解

这篇文章将为大家详细讲解有关ASP.NET Page该怎么理解,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Page,我想每个ASP.NET开发人员对它应该都是比较熟悉的。

这次的博客我就打算专门谈谈它。不过呢,我不打算说 在Page中使用控件的一些话题,也不会说Page的生命周期的相关话题,因为我认为这些话题被人谈论的次数实在是太多了,尤其是市面上的ASP.NET的书籍,都会比较喜欢这些话题。

我不喜欢重复,因此今天我只想谈些人家不谈的那点事,但我认为它们仍然很重要。

一些重要的Page指令

虽然Page公开了很多属性,让我们可以在运行时调整它的状态与行为,但是,还有些重要的参数却是以“指令”方式提供的,需要在设计时就指定。

下面是我整理的一些我认为 比较重要并且经常需要使用的指令:

ASP.NET Page该怎么理解

web.config的全局设置

前面我介绍了一些常用的Page指令,考虑到方便性,ASP.NET还允许我们在web.config中为一些常用的指令配置默认值。下面我就一些常用的场景来说明这些全局配置的方便性。

通常,我在创建一个网站项目时,肯定会决定不使用ViewState和Session的。那么如果为每个页面设置EnableViewState,EnableSessionState指令属性,那就显得太麻烦了,而且还容易遗漏。此时,我们可以直接在web.config中为这些参数指定一个全局的默认值:

<pages enableViewState="false" enableSessionState="false"></pages>

补充说明一下:全局禁用Session的彻底方法是把Session对应的HttpModule从httpModules列表中移除。

web.config允许我们设置Page默认参数的具体配置节如下:

<pages          buffer="[True|False]"    enableEventValidation="[True|False]"    enableSessionState="[True|False|ReadOnly]"    enableViewState="[True|False]"    enableViewStateMac="[True|False]"    smartNavigation="[True|False]"    autoEventWireup="[True|False]"    pageBaseType="typename, assembly"    userControlBaseType="typename"    validateRequest="[True|False]"    masterPageFile="file path"      theme="string"    styleSheetTheme="string"    maxPageStateFieldLength="number"      compilationMode="[Always|Auto|Never]"      pageParserFilterType="string"      viewStateEncryptionMode="[Always|Auto|Never]"      maintainScrollPositionOnPostBack="[True|False]"      asyncTimeout="number" >    <controls>...</controls>    <namespaces>...</namespaces>    <tagMapping>...</tagMapping> </pages>

为了代码重用,设计用户控件也是很常用的方法。

我们可以使用 @ Register指令 在页面注册需要使用的UserControl或者WebControl。然而,有些控件比较通用,许多页面都会使用它,那么就不要再使用 @ Register指令了,可以在web.config中统一注册。例如:

<pages>     <controls>         <add tagPrefix="fish" tagName="MainMenu" class="lazy" data-src="~/Controls/MainMenu.ascx" />         <add tagPrefix="fish" tagName="PageHeader" class="lazy" data-src="~/Controls/PageHeader.ascx" />     </controls> </pages>

有了这个定义后,我就可以在任何页面中直接使用:

<fish:PageHeader runat="server" ID="PageHeader1" />

对于喜欢使用页面内联代码的人来说,可能经常需要使用自己定义的类型。如果这些类型定义在某个命名空间中,那么就需要在内联代码中采用完整命名空间的写法。虽然这样做没有什么问题,但就是麻烦,于是,我们可以在页面中使用 @ Import指令 来导入我们需要使用的命名空间,但是这个指令每次只能导入一个命名空间,而且每个页面还得重复导入,显然不够方便。

为了方便使用一些常用的命名空间,我们可以在web.config中统一指定,例如:

<pages>     <namespaces>         <add namespace="MyMVC" />         <add namespace="WebSiteCommonLib" />         <add namespace="WebSiteModel" />     </namespaces> </pages>

这样设置后,所有页面就可以直接使用这些命名空间下的类型了。

不知道有些人想过:为什么在页面中使用某些微软提供的类型就不需要导入命名空间?

答案是:其实ASP.NET已经将一些微软认为常用的命名空间在web.config中配置好了:

<pages>     <namespaces>         <add namespace="System"/>         <add namespace="System.Collections"/>         <add namespace="System.Collections.Specialized"/>         <add namespace="System.Configuration"/>         <add namespace="System.Text"/>         <add namespace="System.Text.RegularExpressions"/>         <add namespace="System.Web"/>         <add namespace="System.Web.Caching"/>         <add namespace="System.Web.SessionState"/>         <add namespace="System.Web.Security"/>         <add namespace="System.Web.Profile"/>         <add namespace="System.Web.UI"/>         <add namespace="System.Web.UI.WebControls"/>         <add namespace="System.Web.UI.WebControls.WebParts"/>         <add namespace="System.Web.UI.HtmlControls"/>     </namespaces> </pages>

现在,有越来越多的人为了方便而使用扩展方法。使用扩展方法的好处是:可以让我们不去关心这些扩展方法定义在那个类中,只要在支持扩展方法的对象上调用就可以了,就像下面的代码这样:

当前用户已登录,登录名:<%= Context.User.Identity.Name.HtmlEncode() %>

然而,在页面中使用扩展方法时,也必须先导入扩展方法的定义类的命名空间。

因此,为了方便,我们可以在web.config中为我们定义的扩展方法导入相应的命名空间:

<pages>     <namespaces>         <add namespace="FishDemoCodeLib" />     </namespaces> </pages>

换个方式使用 Page

在传统的WEB开发模式下,我们通常会设计一些页面(Page)响应来自用户浏览器的请求,在这种模式下,Page会将***生成的整页HTML代码直接发送给用户浏览器。然而,在某些时候,我们只需要生成一个HTML片段:

在AJAX请求中,客户端为了局部刷新,只要求服务端返回一个HTML片段。

BigPipe方式下,为了能分块输出,每次也只需要输出一个HTML片段。

如果只是为了得到一段简单的HTML代码,可能有些人会选择采用代码来拼接,但是如果那段HTML还有些复杂呢?显然拼接方法肯定是不行的。

对于***个问题,可能有人说:我可以创建一个页面,只放部分代码到页面上。的确,这种方法可以勉强解决***个问题,但是,很有可能那部分代码在整页输出时也会用到,怎么办?

做成UserControl,然后放在一个单独的页面中!其实这种做法很无奈,因为那个容器页面的意义不大(仅仅是个容器),***搞得项目中一大堆页面文件!事实上,这种方法仅适用于使用简单服务端控件的场合,如果想使用一些高级的服务端控件,它根本就不行。

为了能实现前面说到的二个需求,我们就不能再按照传统的方式来使用Page了。因为我们希望能得到(返回)一段HTML。

有二种方法可以让我们继续使用页面模板代码的方式生成HTML代码:

Server.Execute()方法。

Page.RenderControl()方法。

下面这段代码来源于 MyMVC框架,这个方法可以根据指定的用户控件以及控件显示所需的数据得到控件的输出结果(一段HTML代码)。

/// <summary> /// 用指定的用户控件以及视图数据呈现结果,***返回生成的HTML代码。  /// 用户控件应从MyUserControlView<T>继承  /// </summary> /// <param name="ucVirtualPath">用户控件的虚拟路径</param> /// <param name="model">视图数据</param> /// <returns>生成的HTML代码</returns> public static string Render(string ucVirtualPath, object model)  {      if( string.IsNullOrEmpty(ucVirtualPath) )          throw new ArgumentNullException("ucVirtualPath");            Page page = new Page();      Control ctl = page.LoadControl(ucVirtualPath);      if( ctl == null )          throw new InvalidOperationException(              string.Format("指定的用户控件 {0} 没有找到。", ucVirtualPath));       if( model != null ) {          MyBaseUserControl myctl = ctl as MyBaseUserControl;          if( myctl != null )              myctl.SetModel(model);      }       // 将用户控件放在Page容器中。      page.Controls.Add(ctl);       StringWriter output = new StringWriter();      HtmlTextWriter write = new HtmlTextWriter(output, string.Empty);      page.RenderControl(write);       // 用下面的方法也可以的。      //HttpContext.Current.Server.Execute(page, output, false);       return output.ToString();  }

整段代码分为以下几个步骤(我已用空行分隔开了):

检查参数。

创建页面容器并加载用户控件。

设置页面(视图)所需的显示数据。

将用户控件添加到Page的Controls集合中。

调用RenderControl或者Execute让Page输出HTML代码。

返回结果。

这段代码很简单,唯独值得介绍的就是第5步,调用它们就可以得到控件输出的HTML代码。

RenderControl或者Execute的差别在于:

RenderControl不支持服务器控件,原因在于它利用了页面的一种独特编译方式,我已在以前的博客中分析过了。

Execute可以支持服务器控件,因为它会执行一次完整的页面生命周期。

注意:上面这段代码就算使用Execute,也只能支持部分简单的服务器控件,因为一些复杂的服务器控件需要在HtmlForm中才能运行。因此,如果需要支持所有的服务器控件,那么还必须创建HtmlForm对象,并调整包含关系,还有就是还需要去掉产生的多余HTML代码。

如果你需要生成整个页面生成的HTML代码,可以参考 MyMVC框架,那里有实现这个功能的完整代码。

重新认识Eval()方法

我想很多人都写过类似下面的代码:

<asp:Repeater ID="repeater1" runat="server">     <HeaderTemplate><ul></HeaderTemplate>     <FooterTemplate></ul></FooterTemplate>     <ItemTemplate>         <li><%# Eval("OrderID")%>,<%# Eval("OrderDate")%>,<%# Eval("SumMoney")%>         </li>     </ItemTemplate> </asp:Repeater>

在这里我要说的是 Eval() 的调用,还不是Repeater控件。

Eval()不仅仅可以读取一个绑定数据项的属性,还可以去读取DataTable中的一个数据列。而且还能完成更复杂的绑定计算:

<li><%# Eval("OrderID")%>,<%# Eval("OrderDate")%>,<%# Eval("SumMoney")%>     ,订单中的***个商品:<%# Eval("Detail[0].ProductName") %> </li>

当然了,对于页面上的数据绑定,用Eval()的确不是性能***的方法,建议还是使用强类型转换的方法。

有时候,尤其是在写反射应用时,时常会有从字符串解析并实现求值计算的需求。那么,前面这个示例中,Eval()的功能是不是值得挖掘呢?我认为答案是肯定的。

通过分析ASP.NET的绑定代码,我发现Eval在内部会调用DataBinder.Eval这个静态方法,这个方法的签名如下:

//     在运行时计算数据绑定表达式。  //  // 参数:  //   container:  //     表达式根据其进行计算的对象引用。此标识符必须是以页的指定语言表示的有效对象标识符。  //  //   expression:  //     从 container 到要放置在绑定控件属性中的公共属性值的导航路径。  //     此路径必须是以点分隔的属性或字段名称字符串,如 C# 中的 "Tables[0].DefaultView.[0].Price"  //     或 Visual Basic 中的 "Tables(0).DefaultView.(0).Price"。  //  // 返回结果:  //     System.Object,它是数据绑定表达式的计算结果。  public static object Eval(object container, string expression);

通过这个签名的注释,我们可以很容易地看出它的用法。

下面我来举个例子把它应用在非绑定的应用中:

我有一个类:

public class TestEvalClass  {      public List<Order> Orders { get; set; }       // Order以及OrderDetail的定义就省略了,我想大家能想像得出来。  }

那么下面的代码是可以运行的:

static void Main()  {      TestEvalClass testObject = GetTestEvalClassInstance();       string productName = (string)System.Web.UI.DataBinder.Eval(testObject, "Orders[0].Detail[0].ProductName");      Console.WriteLine(productName);  }

对于这个示例,我想输出什么结果,并不重要。

我只想说:如果让你去解析那个表达式,会不会比较麻烦,现在有现成的,用起来是不是很方便?

不用基类也能扩展

在一个ASP.NET网站中,如果想为所有的页面添加某个功能,我们通常会想到使用基类的方式去实现。这的确是一种很有效的方法,但不并唯一的方法,还有一种方法也能容易实现这个需求,那就是使用PageAdapter的方式。

在我写博客的过程中,我写了很多示例页面,页面中包含一些提交按钮是少不了的事情,然而,为了能让示例代码看起来比较原始(简单),我尽量不使用服务器控件,因此就要面临提交按钮的事件处理问题。在博客【细说 ASP.NET Cache 及其高级用法】的示例代码中,我开始采用PageAdapter这种方法,它可以让代码很简单,而且以后也方便以后重用(只需要复制几个文件即可)。

或许有些人认为:扩展所有页面的功能,还是使用基类比较好。

对于这个观点,我完全不反对。

但是,PageAdapter的好处在于它的可插拔性(类似HttpModule的优点)。不过,我当时设计这种扩展方式只是想再换个方法尝试一下而已。

其实微软设计PageAdapter的本意是为了处理各种浏览器的兼容问题,但是我把这个功能用到扩展Page的功能上去了。 HttpModule可以进入到ASP.NET请求管线的任何阶段,但它就是进入不了页面的生命周期中,有了这个方法,我们就可以采用HttpModule这种【外挂】式的方法进入到页面生命周期中,我认为是很有意义的。

方法多了,我想不是件坏事。每种方法都有适合它们的应用场合,了解更多的方法,以后就能做出更优秀的设计。

这次想到这个话题是因为前面的博客【细说ASP.NET Forms 身份认证】中的示例代码。有些人看到那些代码,发现代码的运行方式比较特别,所以,今天我就打算着重介绍这种方法。

我们再来回顾一下以前博客中的示例代码,首先从页面代码开始:

<fieldset><legend>普通登录</legend><form action="<%= Request.RawUrl %>" method="post">     登录名:<input type="text" name="loginName" style="width: 200px" value="Fish" />     <input type="submit" name="NormalLogin" value="登录" /> </form></fieldset>    <fieldset><legend>包含【用户信息】的自定义登录</legend>    <form action="<%= Request.RawUrl %>" method="post">     <table border="0">     <tr><td>登录名:</td>         <td><input type="text" name="loginName" style="width: 200px" value="Fish" /></td></tr>     <tr><td>UserId:</td>         <td><input type="text" name="UserId" style="width: 200px" value="78" /></td></tr>     <tr><td>GroupId:</td>         <td><input type="text" name="GroupId" style="width: 200px" />         1表示管理员用户          </td></tr>     <tr><td>用户全名:</td>         <td><input type="text" name="UserName" style="width: 200px" value="Fish Li" /></td></tr>     </table>          <input type="submit" name="CustomizeLogin" value="登录" /> </form></fieldset>

在这段页面代码中,我定义了二个表单,它们包含各自的提交按钮(其实这也只是部分代码)。

再来看后台处理代码是如何响应提交请求的:

public partial class _Default : System.Web.UI.Page   {      [SubmitMethod(AutoRedirect = true)]      public void NormalLogin()      {          // 省略登录处理代码。          // 如果需要知道这段代码可以浏览下面的网址:          // http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html       }       [SubmitMethod(AutoRedirect = true)]      public void CustomizeLogin()      {          // 省略登录处理代码。          // 如果需要知道这段代码可以浏览下面的网址:          // http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html       }

注意观察,这二个C#方法的名称与页面二个submit按钮的name属性相同,因此可以猜测到这二个C#方法可以处理那二个submit按钮的提交请求。那么这二段代码是如何运行起来的呢?有些人或许看到了[SubmitMethod]的使用,认为与它们有关。其实这种说法并不正确,我也可以完全不使用它们。请记住:Attribute永远只是一个标记,它不可能让代码自动运行起来。

前面的代码能运行起来,与App_Browsers目录下的Page.browser文件有关,此文件的代码如下:

<browsers>     <browser refID="Default">         <controlAdapters>             <adapter controlType="System.Web.UI.Page"                      adapterType="FishDemoCodeLib.MyPageAdapter, FishDemoCodeLib" />         </controlAdapters>     </browser> </browsers>

这里定义了一个MyPageAdapter,它用于Page控件的请求过程。 refID="Default" 表示是对ASP.NET定义的Default.browser文件补充一些配置,它将能匹配来自所有浏览器的请求。

我再来看一下MyPageAdapter的代码:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]  public class SubmitMethodAttribute : Attribute  {      public bool AutoRedirect { get; set; }  }   internal sealed class MethodInvokeInfo  {      public MethodInfo MethodInfo;      public SubmitMethodAttribute MethodAttribute;  }   public class MyPageAdapter : System.Web.UI.Adapters.PageAdapter  {      private static readonly Hashtable s_table = Hashtable.Synchronized(new Hashtable());       private static MethodInvokeInfo[] GetMethodInfo(Type type)      {          MethodInvokeInfo[] array = s_table[type.AssemblyQualifiedName] as MethodInvokeInfo[];          if( array == null ) {              array = (from m in type.GetMethods(BindingFlags.Instance | BindingFlags.Public)                       let a = m.GetCustomAttributes(                              typeof(SubmitMethodAttribute), false) as SubmitMethodAttribute[]                       where a.Length > 0                       select new MethodInvokeInfo {                               MethodInfo = m, MethodAttribute = a[0] }).ToArray();               s_table[type.ToString()] = array;          }          return array;      }        protected override void OnLoad(EventArgs e)      {          base.OnLoad(e);           if( Page.Request.Form.AllKeys.Length == 0 )              return;    // 没有提交表单           MethodInvokeInfo[] array = GetMethodInfo(Page.GetType().BaseType);          if( array.Length == 0 )              return;           foreach( MethodInvokeInfo m in array ) {              if( string.IsNullOrEmpty(Page.Request.Form[m.MethodInfo.Name]) == false ) {                  m.MethodInfo.Invoke(Page, null);                   if( m.MethodAttribute.AutoRedirect                                   && Page.Response.IsRequestBeingRedirected == false )                      Page.Response.Redirect(Page.Request.RawUrl);                   return;              }          }      }  }

这段代码并不长,核心代码更是比较少。

代码中,最重要的一块是MyPageAdapter的实现,它继承了System.Web.UI.Adapters.PageAdapter,并重写了OnLoad方法(相当是在重写Page的OnLoad方法),也正是由于这个重写,代码才有机会在页面的生命周期中被执行,这一点是HttpModule做不到的。

在OnLoad方法中做了以下事情:

检查是不是发生了表单提交的操作。

获取当前页面类型的所有[SubmitMethod]修饰过的方法。

检查提交的表单数据中,是否存在与name对应的C#方法名。

如果找到一个匹配的方法名,则调用。

如果在[SubmitMethod]中设置了AutoRedirect=true,则引发重定向。

注意:如果不调用base.OnLoad(e); 那么页面的Load事件根本不会发生。也就是说:PageAdapter.OnLoad的调用时间要早于Page.Onload方法。

由于这段代码仅供我写示例代码时使用,因此并没有检查要调用的方法的参数是否满足条件,也没有优化刻意去优化它的性能。在我的设计中,被调用的方法应该是无参的,因此是容易判断的,而且可以使用一个固定签名的委托去优化它的,这些细节留着以后再去完善它吧!

关于ASP.NET Page该怎么理解就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ASP.NET Page该怎么理解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

ASP.NET Page该怎么理解

这篇文章将为大家详细讲解有关ASP.NET Page该怎么理解,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Page,我想每个ASP.NET开发人员对它应该都是比较熟悉的。这次的博客我就打算
2023-06-17

Linux该怎么理解

今天就跟大家聊聊有关Linux该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。初次接触 Linux,读者有必要了解一下 Linux 是什么、Linux 的发展现状、Linux
2023-06-28

DB2 export该怎么理解

DB2 export该怎么理解,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。EXPORT实用程序使用SQL select语句或XQUERY语句抽取数据,并将信息放到文件中。可使
2023-06-06

Ruby变量该怎么理解

这篇文章主要为大家分析了Ruby变量该怎么理解的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“Ruby变量该怎么理解”的知识吧。Ruby 是一种开源的面向对象
2023-06-28

Java Spring AOP该怎么理解

这篇文章给大家介绍Java Spring AOP该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序
2023-06-22

Django REST Framework该怎么理解

今天就跟大家聊聊有关Django REST Framework该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.Django REST framework框架介绍Djang
2023-06-02

Asp.net 5中的ApplicationBuilder怎么理解

本文小编为大家详细介绍“Asp.net 5中的ApplicationBuilder怎么理解”,内容详细,步骤清晰,细节处理妥当,希望这篇“Asp.net 5中的ApplicationBuilder怎么理解”文章能帮助大家解决疑惑,下面跟着小
2023-06-26

ASP.NET WebForm重写URL怎么理解

本篇内容主要讲解“ASP.NET WebForm重写URL怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ASP.NET WebForm重写URL怎么理解”吧!进行开发ASP.NET We
2023-06-17

UI设计该怎么理解

这篇文章的内容主要围绕UI设计该怎么理解进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!什么是UI设计?1.定义UI即User Interface(用
2023-06-05

C语言常量该怎么理解

C语言常量该怎么理解,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。什么是常量从字面上简单解释就是不变的量叫常量常量都有哪些字面常量const修饰的常变量#define定义的标识
2023-06-22

Kubernetes中的网络原理解析该怎么理解

这篇文章给大家介绍Kubernetes中的网络原理解析该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。01 覆盖网络覆盖⽹络(overlay network)是将TCP数据包装在另⼀种⽹络包⾥⾯进⾏路由转发和通
2023-06-04

Java内存模型该怎么理解

这篇文章主要讲解了“Java内存模型该怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java内存模型该怎么理解”吧!1.为什么会误解首先,我们先来分析一下问什么很多人,甚至是大多数人
2023-06-16

基于Linux的Windows该怎么理解

基于Linux的Windows该怎么理解 ,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。开源创始人之一的Eric S. Raymond认为,Windows的未来是一层关于Lin
2023-06-28

ASP.NET MVC Bootstrap极速开发框架该怎么构建

这期内容当中小编将会给大家带来有关ASP.NET MVC Bootstrap极速开发框架该怎么构建,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。前言每次新开发项目都要从头开始设计?有木有一个通用的快速开发
2023-06-17

Java虚拟机内存管理该怎么理解

今天就跟大家聊聊有关Java虚拟机内存管理该怎么理解,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java虚拟机规范将物理内存(主内存和CPU中的缓存、寄存器)划分为程序计数器、Ja
2023-06-02

JavaScript函数柯里化该怎么理解

本篇文章给大家分享的是有关JavaScript函数柯里化该怎么理解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、简单了解apply和callcall 和 apply 都是为
2023-06-26

java类的组成结构该怎么理解

这篇文章给大家介绍java类的组成结构该怎么理解,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。成员变量成员变量便是在类中定义的变量。例如这样:public class POP { int a = 1;}而成员变量
2023-06-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录