创建可变类而不使用
中的finalnamespace getPostgeocode
{
class Program
{
/*private static string geos = "geographies";
private static string addresses = "addressbatch";
private static string benchmark = "Public_AR_Current";
private static string vintage = "Current_Current";
private static string returntype = "locations";
private static string returntype = "locations";*/
static void Main(string[] args)
{
//StringBuilder paramURI = new StringBuilder();
// Create a request instance.
// paramURI.AppendFormat(format: @"{0}?benchmark={1}&vintage={2}&returntype={3}"
//, arg0: benchmark, arg1: vintage, arg2: returntype);
string baseURI = "http://geocoding.geo.census.gov/geocoder/";
var uriBuilder = new UriBuilder(baseURI);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["benchmark"] = "Public_AR_Current";
query["vintage"] = "Current_Current";
query["returntype"] = "locations";
query["geo"] = "geographies";
query["addressbatch"] = "addressbatch";
uriBuilder.Query = query.ToString();
baseURI = uriBuilder.ToString();
WebRequest myRequest = WebRequest.Create(baseURI);
myRequest.Method = "POST";
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
myRequest.ContentType = "multipart/form-data; boundary=" + boundary;
//myRequest.KeepAlive = true;
myRequest.Credentials = CredentialCache.DefaultCredentials;
Console.WriteLine(baseURI);
Console.ReadLine();
WebResponse geoResponse = myRequest.GetResponse();
Stream dataStream = geoResponse.GetResponseStream();
StreamReader geoReader = new StreamReader(dataStream);
string addString = geoReader.ReadToEnd();
dataStream.Close();
geoResponse.Close();
}
}
}
而是仅使用没有final的常规类声明,如
public final class X {...}
然后使用静态工厂构造函数,私有构造函数,其中所有字段都是私有的,那么我的问题是 - 不足以声明没有最终字段的私有字段,例如< / p>
public class X {...}
或/为什么我还要说
private double d;
我唯一的答案就是我不会在课堂上错误地改变任何非最终字段,但是有人可以从外面改变吗?
答案 0 :(得分:-1)
无论您是否添加final
,都无法触及该类代码之外的值。
如果你最好能够将它们声明为final,那么它会给编译器提供更多关于这些行为的线索,以便它可以更积极地优化代码。最后一个字段也是线程安全的,而你可能会在延迟初始化时弄乱非私有字段的状态。
我的建议是,除非有明显的性能提升,否则您总是尽可能地宣布最终版并且不进行延迟/延迟初始化。
同样非常重要的是要记住,对数组或非免疫对象的final
引用不保证如果您共享参考值,其内容不会被更改(例如,返回它直接通过吸气剂)。对于裸阵列没有解决方法,但对于java.util.*
个集合,您总是可以共享对您的集合的不可修改的包装引用(请参阅Collections.unmodifiableXXXX
方法)。
最后请注意,尽管使用private
声明某个字段为final
,但仍可使用某些时髦的低级别工具更改这些值(例如,请参阅this)。然而,在编程时,没有人应该真正担心这一点。
答案 1 :(得分:-1)
Immutable 的类意味着在该类的实例具有该类 state 和/或 value(s)之后无法更改已创建。使类不可变可以通过多种方式实现;使用final
变量可以提供帮助,并且使类本身final
可以通过阻止子类可以打破不变性规则的子类来提供帮助。
在类上使用final
关键字而在变量上使用它意味着两个完全不同的东西。
将类设置为final意味着类不能被子类化;也就是说,如果你有
public final class X {...}
你不能扩展它
public class Y extends X {...} // Illegal!
类是否为final是否与类成员变量无关。
将变量设置为final
,无论是static
,类成员变量还是本地(对方法或块)变量都意味着变量无法更改后它已被赋值。
您的代码还需要通过任何可用的执行路径为最终变量设置一个值,所以这没关系,因为它始终将“max”设置为:
...
final int max;
if (parameter) {
max = 100;
} else {
max = 1000;
}
但这会给你一个错误:
...
final int max;
if (parameter) {
max = 100;
}
因为如果“参数”评估为true
,则设置为“max”,否则不设置“max”。
这通常在不可变对象的构造函数中完成:
public final class X
{
final int value;
public X(int v)
{
this.value = v; // Now that `value` has been set
// it can never be changed
}
}
将某个类声明为final
并不意味着它的类成员是最终的,所以你的问题“为什么我还要说”是因为{{em>的这两种用法1}}是不相关的。
请注意,您还可以将方法声明为最终方法:
final
这意味着不允许子类使用新实现覆盖此方法。如果类已经是public final int getMax() {...}
,那么方法上的final
没有意义,因为没有任何子类试图覆盖该方法。)