我们在看书的时候常常看到书上说暴露属性不安全,那么请问下哪里不安全呢?不安全在何处呢?
上网查了些资料,似乎看不出网上说的那些有何不安全。
IBM网站的一篇文章(您的 Java 代码安全吗 — 还是暴露在外?-->限制对变量的访问)写道:因为变量为 public 的,所以它暴露了。将其改成以private修饰,用get/set赋值的方式来使之安全的代码。
文章链接:
http://www.ibm.com/developerworks/cn/java/j-staticsec/index.html
即使你禁止掉了在子类中用this.name = name;来改变从父类继承过来的name属性值,可你还是可以在子类中用从父类继承过来的setName()方法改变从父类继承过来的name属性值。
百度知道中的一篇文章写道:get/set方法也不一定只是简单的作一个赋值,或一个返回值吧,在这里可以作一些权限的控制,比如不是每个角色都可以赋值的。再比如返回的值不一定是值本身,可以是经过处理了的,比如加密,这用public定义是不能作到的。
文章链接:
http://zhidao.baidu.com/question/115580824.html
在get/set中是可以做一些处理,但这和安全无关,我们取到值后也一样可以做这些处理。不是吗?
网上对这个问题的资料不多,以下是我研究暴露属性不安全的一点,欢迎大家一起讨论。
class Parent {
public String name = "PARENT"; //暴露属性
public void fn() {
System.out.println(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Son extends Parent {
public String name = "SON"; //暴露属性
public void fn() {
System.out.println(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("TEST1:");
Parent s = new Son(); //通常以父类或接口编程
System.out.println(s.name); //注意:取得的是父类属性值
System.out.println(s.getName()); //这才是期望值
s.fn();
System.out.println();
System.out.println("TEST2:");
s.name = "A"; //不安全,改变的是父类属性值,子类属性值并没有改变
System.out.println(s.name);
System.out.println(s.getName());
s.fn();
System.out.println();
System.out.println("TEST3:");
s.name = "PARENT"; //把设回初始状态
s.setName("A"); //安全,改变的子类属性值
System.out.println(s.name);
System.out.println(s.getName());
s.fn();
}
}
/**OutPut
TEST1:
PARENT
SON
SON
TEST2:
A
SON
SON
TEST3:
PARENT
A
A
*/
Java的框架一般都是以接口(Interface)编程,这是为了通用性。而接口中定义的属性都默认是public static final的,根据上面例子,当实现类向上转型到接口,就不能直接把值赋给属性(因为接口的属性是final的),而要用set方法
interface P {
String name = "Bruce";
void setName(String name);
String getName();
}
class S implements P {
private String name = "Phil";
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
public class Test {
public static void main(String[] args){
P p = new S();
//p.name = "Phil"; //The final field P.name connot be assigned
p.setName("Phil");
System.out.println("P.name=" + p.name);
System.out.println("S.name=" + p.getName());
}
}
/**OutPut
P.name=Bruce
S.name=Phil
*/
上网查了些资料,似乎看不出网上说的那些有何不安全。
IBM网站的一篇文章(您的 Java 代码安全吗 — 还是暴露在外?-->限制对变量的访问)写道:因为变量为 public 的,所以它暴露了。将其改成以private修饰,用get/set赋值的方式来使之安全的代码。
文章链接:
http://www.ibm.com/developerworks/cn/java/j-staticsec/index.html
即使你禁止掉了在子类中用this.name = name;来改变从父类继承过来的name属性值,可你还是可以在子类中用从父类继承过来的setName()方法改变从父类继承过来的name属性值。
百度知道中的一篇文章写道:get/set方法也不一定只是简单的作一个赋值,或一个返回值吧,在这里可以作一些权限的控制,比如不是每个角色都可以赋值的。再比如返回的值不一定是值本身,可以是经过处理了的,比如加密,这用public定义是不能作到的。
文章链接:
http://zhidao.baidu.com/question/115580824.html
在get/set中是可以做一些处理,但这和安全无关,我们取到值后也一样可以做这些处理。不是吗?
网上对这个问题的资料不多,以下是我研究暴露属性不安全的一点,欢迎大家一起讨论。
class Parent {
public String name = "PARENT"; //暴露属性
public void fn() {
System.out.println(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Son extends Parent {
public String name = "SON"; //暴露属性
public void fn() {
System.out.println(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("TEST1:");
Parent s = new Son(); //通常以父类或接口编程
System.out.println(s.name); //注意:取得的是父类属性值
System.out.println(s.getName()); //这才是期望值
s.fn();
System.out.println();
System.out.println("TEST2:");
s.name = "A"; //不安全,改变的是父类属性值,子类属性值并没有改变
System.out.println(s.name);
System.out.println(s.getName());
s.fn();
System.out.println();
System.out.println("TEST3:");
s.name = "PARENT"; //把设回初始状态
s.setName("A"); //安全,改变的子类属性值
System.out.println(s.name);
System.out.println(s.getName());
s.fn();
}
}
/**OutPut
TEST1:
PARENT
SON
SON
TEST2:
A
SON
SON
TEST3:
PARENT
A
A
*/
Java的框架一般都是以接口(Interface)编程,这是为了通用性。而接口中定义的属性都默认是public static final的,根据上面例子,当实现类向上转型到接口,就不能直接把值赋给属性(因为接口的属性是final的),而要用set方法
interface P {
String name = "Bruce";
void setName(String name);
String getName();
}
class S implements P {
private String name = "Phil";
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
public class Test {
public static void main(String[] args){
P p = new S();
//p.name = "Phil"; //The final field P.name connot be assigned
p.setName("Phil");
System.out.println("P.name=" + p.name);
System.out.println("S.name=" + p.getName());
}
}
/**OutPut
P.name=Bruce
S.name=Phil
*/