Access control to method in Java - java

I'm doing this for educational purposes, so imagine that i have an objects called A, B and C, if B calls a method on A, A will do it, if C calls a method on A, A won't do it.
An analouges, Imaging A is you, B is your dad and C is someone else, if your dad tells you something, you have to do it without asking, if someone else tells you something, you aren't obliged to do it.
I didn't find an answer for this behavior, please someone can describe how to do it, and shows me an example in Java.

This code would be one way to do it if you included a list of bosses in the constructor:
public class Me {
private ArrayList<Object> bosses=new ArrayList<Object>();
public Me(ArrayList<Object> myBosses) {
this.bosses=myBosses;
}
public void AnOrderToDo(Object orderer,int randomArg){
for(Object o:bosses){
if(o==orderer){
//TODO method code here
}
}
}
}

You can create a package containing only classes A and B and use the default access modifier for the methods that should not be called from other classes.
The default access modifier allows only the class itself and classes in the other packages to see the methods, so if C is in another package will not even be able to see the method.
Example:
Class A in package stackoverflow.defaultModifier
package stackoverflow.defaultModifier;
public class A {
//NOTICE THE ABSENCE OF PUBLIC/PRIVATE/PROTECTED, is using the default access modifier
void printHello(){
System.out.println("hello");
}
}
Class B in package stackoverflow.defaultModifier can access to printHello()
package stackoverflow.defaultModifier;
public class B {
public static void main(String[] args) {
A a = new A();
a.printHello();
}
}
Class C in package stackoverflow.externalClasses cannot access printHello() (Error: printHello() is not public in class A, cannot be accessed from outside package)
package stackoverflow.externalClasses;
import stackoverflow.defaultModifier.A;
public class C {
public static void main(String[] args) {
A a = new A();
a.printHell(); //compilation error!
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

Related

Getting an instance of the subclass extending a superclass when a method is called

So, I want to be able to get an instance of a subclass that is being run when it calls a method from the super class. For example, if I had this class:
public class A {
public void aMethod() {
//Here is where I want to see if class B is calling the code
}
}
public class B extends A {
}
public class C {
B b = new B();
b.aMethod();
}
And, like the comment says, I want to check, in aMethod, if class B, the subclass of class A, is calling the code.
As has been pointed out to you, there is almost never a good reason to do this and I agree that you should be using polymorphism instead. However, if you "need" to do this or just want to know how to go about doing something like this, you can use instanceof on this inside of the method:
class A {
public void aMethod() {
if (this instanceof B) {
System.out.println("I'm a B!");
}
}
}
public class B extends A {
public static void main(String[] args) {
B b = new B();
b.aMethod();
}
}
public class A {
public void aMethod() {
if(this.getClass() == B.class){
System.out.println("huhuhuuuuuuuuuuuuuuuuu");
}
}
}
public class B extends A {
}
public class C {
public static void main(String[] args) {
B b = new B();
b.aMethod();
}
}
Check here: How to get the caller class in Java
The 2nd part of the answer from #dystroy is probably a start.
Note that this finds a call at any depth:
for(final StackTraceElement element : Thread.currentThread().getStackTrace()) {
if (element.getClassName().equals(B.class.getName())) {
System.out.println("BINGO");
}
}
If you want to check only a limited depth, don't iterate through all of the array.
This can be useful e.g. if some framework forces you to have a special method or a no-arg constructor to be present, but you don't want any developer to call this method directly. (Yes, it is a hack, but sometimes odd frameworks force you to do odd things). Then you can have an assertion in the unwanted method that just throws an exception if it is called by the wrong corner of your code.
Anyway you should try do avoid things like this if possible.

Getting declaring class in Java

Having something like in Java:
class A {}
class B {private A a;}
class C {private A a;}
How could I know which is the class that declared a ?
I.e. I want to get class B or class C
Any ideas are appreciated.
Regards
You couldn't just with the structure you've specified. You'd have to pass a reference to an instance of B or C into A's constructor, then write some logic to determine the type passed in.
class A {
public void print(){
String className = new Exception().getStackTrace()[1].getClassName();
System.out.println(className);
}
}
class A1 {
private A a;
public A1(){
a= new A();
a.print();
}
}
class A2 {
private A a;
public A2(){
a= new A();
a.print();
}
}
public class C {
public static void main(String[] args) {
A1 a1= new A1();
A2 a2 = new A2();
}
}
You have to do someting like:
class A {
boolean itWasC;
public A( C objectC ) {
itWasC = true;
}
public A( B objectB ) {
itWasC = false;
}
}
And once you create an object of class "A" from class B or class C pass this to the constructor. For example: A objectA = new A( this )
It is weird, and you can't do it without instanciating objects.
As i understand the question you need to find all usages of class A (type usages) in your code (Please correct me if i'm wrong).
It depend on your IDE and the installed plugins for code inspection, most IDE's provide such a functionality, in Eclipse for example you can right click a Class and select "References->Project"
And if your IDE does not have this there are alot of tools for java, take a look at: A tool like ReSharper, but for Java?
you cannot do that in java unless you have a reference of the Object in Class A... definitely not through programatically nor in runtime.
But if you just want to find out the classes that are referencing Class A , one option is to rename the class to something else and try to compile.
And Voila , compiler would list all the classes that Reference Class A , but cannot resolve to a type.
Another alternative ,would be to use Reflections to find out the Variables in a Class and compare if the type of the variable is of Class A type
Heres a sample Program i wrote to do just that
import java.lang.reflect.Field;
import com.test.ClassA;
package com.test;
public class ClassA {
}
public class ClassB {
private ClassA classA;
public static void main(String[] args) throws Exception,
NoSuchFieldException {
Field classVariable = ClassB.class
.getDeclaredField("classA");
classVariable.setAccessible(true);
System.out.println(classVariable.getType());
System.out.println(ClassA.class);
if (ClassA.class.equals(classVariable.getType())) {
System.out.println("Class A is referenced");
}
}
}
Result
class com.test.ClassA
class com.test.ClassA
Class A is referenced

How to make some methods from superclass not avaliable in child class

Lets say I have a class
public class Base {}
and a child class
public class Derived extends Base {
public void Foo(Object i){
System.out.println("derived - object");
}
}
and main class
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
}
}
In console we will see
derived - object
Some time later I want to modify my superclass like this :
public class Base {
public void Foo(int i) {
System.out.println("base - int");
}
}
Now if I run my programm I will see:
base - int
So can I make a method in superclass not avaliable in my child class?
In result I want to see derived - object.
I see some don't understand what I want so I'll try to explain:
I want to modify only superclass and I don't want to modify my child class.. for example if I will make jar with my superclass and jar with my childs. I don't want to change all jars.. I want to add method into superclass and make it avaliable for superclass..
And such code
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
Base b = new Base();
b.Foo(i);
}
}
give me
derived - object
base - int
You should use following signature for Foo method in base class:
public void Foo(Object i) {
System.out.println("base - int");
}
This way you can override method Foo from base class. Now you do not override this method but overload it instead.
If you want to use public void Foo(int i) signature in your base class then you can define Foo method in base class as private.
PS: I hope that I've understood you.
private members are limited to the class scope.
default (no keyword for this one) are limited to other members of the same package.
protected are limited to hierarchy.
public are not limited.
So if you don't want your child class to access a member of the superclass (member means methods, enum, variables ...) you should declare your foo like this :
public class Base {
private void Foo(int i) {
System.out.println("base - int");
}
}
Edit from my comment :
if you dont want child class to access a parent's member at compile time I can't see any way to still allow external classes to access it.
You want to block access from close scope while allowing broader scope. This can only be done by overriding the method and throwing an exception for accessviolation or something which is not at compile time but at runtime. Although you could make it work with a custom annotations but I don't know how to do this.
You can make a method final, which means, that the child class cannot override it.
If you do not do that and the child class overrides the method, you cannot call the super classes method from your main.
A Convention note: Please use lowercase method names in java.
package com.abc;
public class TestParentChild {
public static void main(String[] asd) {
Base b = new ChildB();
b.foo(5);
}
}
class Base {
public void foo(int i) {
System.out.println("derived - int");
}
}
class ChildB extends Base {
public void foo(int i) {
System.out.println("derived - object");
}
}
This might help you

Equivalent to late static binding(PHP) in other popular languages

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test(); // Outputs "B"
?>
I want to get an equivalent in Java...so something like
class A {
public static void who(){
System.out.println("A");
};
public static void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
public static void who(){
System.out.println("B");
};
public static void main(String[] args){
B.test(); // Outputs "A" but I want "B"
}
}
I want the who() call inside A::test to resolve as in PHP 5.3 by calling B::who.
EDIT: I know there is no "standard way" of doing this in most popular languages. I'm looking for hacks and such. Also, is this possible in C/C++, or any other popular OOP language?
This is not for any real design on anything. I'm just being curious.
Not possible in Java. (At least not without ugly reflection hacks.)
I encourage you to rethink your design and rely on proper objects.
Related question:
Can I override and overload static methods in Java?
Edit: B.test() will (or can at least according to spec) be compiled into a call to A.test(), so there's no way to discover how the call was made from within A.test(). In other words, there's no way to let the behaviour of A.test depend on if it was called through A.test() or B.test().
Since you're asking out of curiosity, here's AFAIK the closest "solution".
Overload test with a test(Class<?> c) which takes as argument the class which defines the intended who method.
Hide (note that you can't override) test() in class B.
And change the implementation of A.test slightly.
In code:
class A {
public static void who() {
System.out.println("A");
}
public static void test() {
test(A.class);
}
public static void test(Class<?> c) {
//who(); //<<< How to implement a static:: thing here???
try {
c.getMethod("who").invoke(null); // Call static who on given class.
} catch (Exception e) {
}
}
}
public class B extends A {
public static void who(){
System.out.println("B");
}
public static void test() {
test(B.class);
}
public static void main(String[] args){
A.test(); // Outputs "A"
B.test(); // Outputs "B"
}
}
It seems that the compiler generates a call to B.test in the bytecode even though B doesn't declare a method named test.
Bytecode of main method:
invokestatic #5 = Method B.test(()V)
return
Given the names of a class and method ("B" and "who") you can easily use reflection to call the method. So the question becomes
Can you extract B by combining the call stack and bytecode inside A.test?
You'll need to use the return address stored on the stack to locate the call to B.test in the bytecode and extract the declared call. There are plenty of bytecode manipulation libraries, but I don't know if any of them allow you to tie that to the execution stack in the JVM.
You can't override static methods in java.
http://geekexplains.blogspot.co.uk/2008/06/can-you-override-static-methods-in-java.html
Here's an example from Java. It uses Java 8 default methods and getClass(). I bet it works with classes too:
interface A {
default String name() {
return getClass().getName();
}
}
class B implements A {}
public class LateBinding {
public static void main(String[] args) {
// Create an anonymous class in `LateBinding` (called `$1`)
System.out.println(new A(){}.name());
// Instantiate a new `B`
B b = new B();
System.out.println(b.name());
}
}
Results:
$ javac LateBinding.java && java LateBinding
LateBinding$1
B
As you can see the method knows in both cases where it's running, although it's defined in A. This example is not really static, because you can't call getClass() statically, but LSB in PHP is not really limited to static contexts.
There is no elegant way to do it with static method declaration (Only Delphi from what I'm aware of supports override for static methods). However if static is not necessary for you you can write something like this:
class A {
public void who(){
System.out.println("A");
};
public void test(){
who(); //<<< How to implement a static:: thing here???
}
}
class B extends A {
#Override
public void who(){
System.out.println("B");
};
public void main(String[] args){
A instance = new A();
instance.test(); // prints 'A'
instance = new B();
instance.test(); // prints 'B'
}
}
EDIT after clarification:
Pretty hacky way of doing this: Thread.currentThread().getStackTrace() then from top-most record get method and class this method belongs to. Having Class c - you could write c.getMethod("who").invoke(null); to call the correspond who() method.

Calling An Inherited Class Method From Java

In Python, class methods can be inherited. e.g.
>>> class A:
... #classmethod
... def main(cls):
... return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>
How would you do the equivalent in Java? I currently have:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
#Override
public void show(){
System.out.println("B");
}
}
I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.
How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?
Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.
Your class B does not have a main method and static methods are not inherited.
The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.
B.main:
public static void main( String[] arg ) {
new B().run();
}
How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?
I think this isn't possible. Here's why:
In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.
The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.
Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.
In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).
In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is:
A
B
B
Hopefully this makes sense.
public class A {
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
public class B extends A {
#Override
public void show(){
System.out.println("B");
}
}
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
A anothera = new B();
a.show();
b.show();
anothera.show();
}
}

Categories